2009-11-29 37 views
5

在C中, 我有一個32位字代表一個地址(我有它存儲在一個無符號長,希望沒關係)。現在從我收集的內容中,地址的一部分包含頁碼,另一部分包含偏移量。我想知道如何才能提取給我頁碼的位。我已經計算出前22位最重要的位是頁碼,其他10位是頁偏移量。我怎樣才能抓取頁碼的位?我想我可以用一些按位操作來做到這一點,但我不知道如何。提取位

+0

好問題 - 我需要爲我編寫的反彙編程序做這件事。 – new123456 2011-07-16 20:33:14

回答

11

使用bitshift運算符來提取所需的位。

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

對於頁碼,>>操作符會將位向下移位,因此您會丟失最不重要的位。對於偏移量,((1 < < 10)-1)創建一個由10個位組成的位掩碼,其用於僅選擇10個最低有效位並忽略最高有效位。

+1

這樣的代碼可能是一個好主意,在你移動它們之後屏蔽這些位,以防硬件進行算術(符號擴展)右移。 pagenumber =(x >> 10)&((1 << 22) - 1); – 2009-12-04 03:36:43

2

我是現場提取「兩班倒」方法的狂熱粉絲。它既可以簽名也可以不簽名。爲了從word提取的寬度w與至少顯著位lsb場:

#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 << y移位x左邊的y % 32位(假設x有32位整數類型)。這意味着如果您嘗試將32位整數左移或右移32位,則結果與無操作相同。 64位類型的64位移位存在類似的問題。

+0

「英特爾普通芯片所做的一切沒有用處」 - 他們做了什麼? – AShelly 2009-12-03 19:31:56

+0

@ashelly:很好的問題;我編輯了答案。誰知道,它可能會讓我讚不絕口:-) – 2009-12-04 02:59:10