linux核心中ffs x 巨集

2021-06-28 18:05:59 字數 1303 閱讀 1008

linux核心中ffs(x)巨集是平台相關的巨集,在arm平台,該巨集定義在

arch/arm/include/asm/bitops.h

#define ffs(x) ()

static inline int fls(int

x)

__t & -__t   等於找到__t 第乙個為1的位(從低位開始),並把該位保留為1其餘位清0. 

例如 一32位整形數 6,用二進位制表示它的低8位:00000110,  都知道負數為最高為1其餘位取反加1.-6即 11111010

相與得 00000010,即6&-6. 把該值傳遞給函式fls().

再看fls函式.

if(__builtin_constant_p(x))

return

constant_fls(x);

__builtin_constant_p 是gcc的內建函式 ,用於判斷乙個值是否為編譯時常數,如果引數的值是常數,函式返回 1,否則返回 0。

如果是常數就用下面函式計算00000010中1的位置

static inline int constant_fls(int

x)

if (!(x & 0xff000000u

))

if (!(x & 0xf0000000u

))

if (!(x & 0xc0000000u

))

if (!(x & 0x80000000u

))

return

r;}

演算法就是折半法,這個函式計算的是從高位起第乙個1位的位置.00000010, r=2.  由於__t&-__t只有乙個1,所以就是找到該1的位置.

如果輸入引數是00001010 那麼 r=4.

如果引數是變數,直接使用arm指令運算.

執行   asm("

clz\t%0, %1

" : "

=r" (ret) : "

r" (x) : "cc"

);ret = 32 -ret;

clz(count leading zeros)指令對rm中值的高位(leading zeros)個數進行計數,結果放到rd中。若源暫存器全為0,則結果為32。若[31]為1,則結果為0。

clz指令計算高位0的個數, 然後拿32-ret 算出1的位置.

所以,ffs(x)這個巨集的值就是x的第乙個1的位置(從低位開始,數值從1開始,0代表x全0).

另外,該檔案中還有很多linux關於位操作的函式,可以作為自己寫應用程式時的有用參考.

linux核心中的list entry巨集

初學linux核心 將學習中的一些知識點儲存起來,方便以後查閱。define list entry ptr,type,member container of ptr,type,member list entry只是一層封裝,實際上起作用的是container of巨集,define containe...

linux核心中的MAX MIN巨集

min max macros that also do strict type checking.see the unnecessary pointer comparison.define min x,y define max x,y and if you can t take the strict...

核心中的current巨集

說明 current巨集,是乙個全域性指標,指向當前程序的struct task struct結構體,即表示當前程序。例如current pid就能得到當前程序的pid,current comm就能得到當前程序的名稱。每個程序會有兩個棧,乙個使用者棧,存在於使用者空間,乙個核心棧,存在於核心空間。當...