2011-09-13 23 views
1

你能解釋我這個代碼嗎?我真的不明白。__range_ok宏中的彙編代碼

http://lxr.free-electrons.com/source/arch/arm/include/asm/uaccess.h#L70

#define __addr_ok(addr) ({ \ 
     unsigned long flag; \ 
     __asm__("cmp %2, %0; movlo %0, #0" \ 
       : "=&r" (flag) \ 
       : "" (current_thread_info()->addr_limit), "r" (addr) \ 
       : "cc"); \ 
     (flag == 0); }) 

/* We use 33-bit arithmetic here... */ 
#define __range_ok(addr,size) ({ \ 
     unsigned long flag, roksum; \ 
     __chk_user_ptr(addr); \ 
     __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \ 
       : "=&r" (flag), "=&r" (roksum) \ 
       : "r" (addr), "Ir" (size), "" (current_thread_info()->addr_limit) \ 
       : "cc"); \ 
     flag; }) 

這是ARM Linux內核,__range_ok

+0

本指南應該有所幫助:http://www.ethernut.de/en/documents/arm-inline-asm.html。有一件事我不明白。它看起來使用了'flag'操作數,甚至是未初始化的,並僅被列爲輸出? – domen

+0

似乎我爲時已晚,無法編輯。在最近的來源中「」是「0」,「0」意味着用來代替第一個寄存器,所以「%0」。我認爲這也應該回答你接受答案的問題。有關更多信息,請參閱http://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html。 – domen

回答

1

由於信息的有關寄存器使用和其他裝飾總彙,看文檔爲GCC Extended Inline Assembly

我建議你通過

運行此源
gcc .... -S 

,看看最終產生的結果是什麼。

您也可以運行

objdump -dC -S <objectfile.o> 

你會從你的交叉編譯工具鏈需要objdump的。 另外,使用調試信息進行編譯以獲取源註釋(-S)。 編譯-O0以避免由於優化造成的混淆。

+1

謝謝!我閱讀所有手冊,但仍然不明白一件事... addr_limit會從哪裏獲得價值?在哪個操作中? – elenbert