2009-11-29 7 views
5

Cで 私はアドレスを表す32ビットワードを持っています(そして、私はそれをunsigned longに格納しました。今私が集めたものから、アドレスの一部にはページ番号が含まれ、他の部分にはオフセットが含まれています。私はどのように私にページ番号を与えるビットを抽出することができたのだろうかと思っていた。私はすでに最初の22の最も重要なビットはページ番号であり、他の10ビットはページオフセットである。ページ番号のビットをどうやって取得できますか?私はいくつかのビット単位の操作でこれを行うことができると考えていますが、どうしたらよいか分かりません。ビットを抽出する

+0

良い質問 - 私は同様に書いている逆アセンブラのためにこれを行う必要があります。 – new123456

答えて

11

bitshift演算子を使用して、必要なビットを抽出します。

pageNumber = x >> 10; 
offset = x & ((1 << 10) - 1); 

ページ番号の場合、>>演算子はビットをシフトダウンするため、最も重要でないビットが失われます。

オフセットの場合、((1 < < 10) - 1)は、10の最下位ビットのみを選択し、最上位ビットを無視するために使用される10のビットマスクを作成します。

+1

ハードウェアが算術(符号拡張)右シフトを行う場合、ビットをシフトした後にビットをマスクすることは、このようなコードでは良い考えです。 pagenumber =(x >> 10)&((1 << 22)-1); –

2

私はフィールド抽出の "2つのシフト"方法の巨大なファンです。署名付きと署名なしの両方で動作します。 wordから最下位ビットlsbと幅wのフィールドを抽出するには:この場合

#define BITSIN(W) (8*sizeof(W)) 
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width); 

BITSIN(word) == 32lsb+width == 32は、その限り、当該単語が符号なしとして、あなただけのマスキングなしで右の10をシフトすることができます。

注意:32ビットタイプの32ビットシフトにご注意ください! C標準はコンパイラに何かをさせ、一般的なIntelのチップは役に立ちません:x << yxビットがy % 32ビット左にシフトします(xは32ビット整数型です)。つまり、32ビット整数を32ビット左または右にシフトしようとすると、結果はノーオペレーションと同じになります。 64ビットタイプの64ビットシフトでも同様の問題があります。

+0

「一般的なIntelのチップは役に立たない」 - 彼らは何をしていますか? – AShelly

+0

@cellelly:良い質問です。私は答えを編集しました。誰が知っている、それは私にupvoteを得るかもしれない:-) –

関連する問題