2012-10-29 5 views
9

このマクロの機能を理解できません。これらはlinux-kernelで定義されていますが、疑いの余地はそれとは無関係です。 (((x)+(mask))&~(mask))行が何をするのか分かりません。マクロカーネルを整列する

#define ALIGN(x,a)    __ALIGN_MASK(x,(typeof(x))(a)-1) 
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 

助けてください。

答えて

19

と同じであるあなたは数を持っていると言う:0x1006

いくつかの理由から、それを4バイト境界に揃えたいとします。 4バイト境界で

は、あなたが知っている整列値はあなたが、その後も0x1006の整列値が0x1008知っている など0x10000x10040x1008、です。

あなたはどうすれば0x1008を取得しますか?アライメント値4ためのアライメントマスクは(4 - 1) = 0x030x1006 + 0x03 = 0x1009

0x1009 & ~0x03 = 0x1008

この操作は、マクロ__ALIGN_MASKあります。

あなたの代わりに直接0x03(アライメントマスク)の値4(アライメント)を渡したい場合は、

11
#define ALIGN(x,a)    __ALIGN_MASK(x,(typeof(x))(a)-1) 

アラインメント、axの型にキャストし、その後一方が減算されます。アライメントは2の累乗でなければならないので、ビットパターン00..011..11の数字がxのタイプであるマスク(k 1sがa = 2^kの場合)が結果として得られます。 (x)+ (mask)が次に大きい倍数よりxより小さく、小さくないアラインメントの最小複数と少なくとも同じ大きさであるように

そして

#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(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) 
+0

マクロALIGNは2 –

+0

のパワー 'alignment'のためにこのトリックの仕事をされないだろうていますいいえ、それは2の累乗に対してのみ機能します。しかし、アライメントの指定は2の累乗にのみ有効です。したがって、有用なケースは誤って処理されません。 –

関連する問題