番号があるとします:0x1006
何らかの理由で、それを 4
に揃えたい バイト境界。
境界が 4 バイトの場合、アラインされた値は 0x1000
であることがわかります 、 0x1004
、 0x1008
など。これで、0x1006
の整列値もわかります 0x1008
です .
どうやって 0x1008
を取得しますか? ?位置合わせ値 4
の位置合わせマスク (4 - 1) = 0x03
です
今0x1006 + 0x03 = 0x1009
と 0x1009 & ~0x03 = 0x1008
この操作は __ALIGN_MASK
です マクロ。
値 4
を渡したい場合 (アライメント) 直接 0x03
の代わりに (位置合わせマスク)、あなたは ALIGN
を持っています マクロ
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
配置、a
、 x
にキャストされます の型で、1 が減算されます。アラインメントは 2 のべき乗である必要があるため、ビット パターンの数は 00..011..11
になります。 x
の の型、マスク (k
a = 2^k
の場合は 1 ).
次に
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
マスクの値を x
に追加します 、だから (x)+ (mask)
x
より小さくないアライメントの最小倍数と少なくとも同じ大きさ そして次に大きい倍数よりも小さい。次に、マスクの補数を使用してビットごとに、その数をアライメントの倍数に減らします。
2^k - 1
形式のマスクの場合 、計算
(x + mask) & ~mask
と同じです
(x + 2^k - 1) - ((x + 2^k - 1) % (2^k))
または
((x + 2^k - 1)/(2^k)) * (2^k)