服用這一步一步:
long __res; //some variable
__asm__ volatile (
"movl $244, %%eax;"
...通過%eax
中的值選擇32位x86 Linux的系統調用。這是系統調用的號碼get_thread_area
。請參閱arch/x86/include/asm/unistd_32.h
(在最近的內核中)獲取系統調用號列表。 (注:系統調用號碼不是32位和64位之間是相同的。)
"movl %1, %%ebx;"
"movl %2, %%ecx;"
"movl %3, %%edx;"
...參數到系統調用在寄存器傳遞。對於32位x86,在寄存器中最多傳遞5個參數,順序爲%ebx
,%ecx
,%edx
,%esi
,%edi
(對於需要它的少數系統調用的第6個參數在用戶堆棧上傳遞)。 %1
,%2
,%3
指內聯彙編程序的「約束」中提到的第2,3和4項(見下文)。
(這似乎有點奇怪,順便說一句:在get_thread_area
系統調用only needs one argument ...)
"int $0x80;"
...調用系統調用。
"movl %%eax,%0"
...系統調用返回結果%eax
; %0
是指約束中提到的第一個項目。
: "=m" (__res) //from here can't understand
...「約束」告訴GCC其中它可以把所使用和產生由聯彙編器塊中的輸入和輸出值。這第一部分(在第一個:
之後)用於輸出。 "=m"
這裏說__res
應該保存在內存中("m"
),並且它是隻寫的,即任何以前的值將被覆蓋("="
)。約束中的操作數可以通過內聯彙編塊中的數字引用(例如,%0
),從0開始出現。
: "m" (a), "m" (b) , "m" (c)
...下一部分是輸入。這表示他們將全部置於記憶中。
: "%eax","%ebx","%ecx", "%edx",
...最後一節中表示「打一頓」寄存器,即,那些將被覆蓋爲一體的內聯彙編塊內的代碼的結果。 GCC會將嵌入式彙編程序塊放入其生成的其他代碼的中間,但它不知道塊內部的指令實際上做了什麼 - 因此您必須告訴它,任何可能在封鎖將不再有效。
);
非常感謝您的回答,只有一個關於clobbered寄存器的問題,我的GCC會在覆蓋之前保存它們? – likeIT 2011-04-07 07:55:25
@likeIT:是的,如果需要,GCC會自行保存它們。 – 2011-04-07 19:58:48