簡體   English   中英

Linux內核中的asm__volatile()

[英]asm__volatile() in Linux Kernel

有人可以解釋一下此功能的確切作用嗎,我嘗試用谷歌搜索它,但是什么也沒找到:

long __res; //some variable

__asm__ volatile (
"movl $244, %%eax;"
"movl %1, %%ebx;"
"movl %2, %%ecx;"
"movl %3, %%edx;"
"int $0x80;"
"movl %%eax,%0"
: "=m" (__res) //from here can't understand
: "m" (a), "m" (b) , "m" (c)
: "%eax","%ebx","%ecx", "%edx",
);

預先感謝您的任何解釋

逐步進行以下操作:

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,最多以%ebx%ecx%edx%esi%edi的順序在寄存器中傳遞五個參數(第6個參數,對於需要它的少數syscalls傳遞給用戶)堆)。 %1%2%3表示內聯匯編程序在“約束”中提到的第二,第三和第四項。

(順便說一下,這似乎有點奇怪: get_thread_area syscall 僅需要一個參數 ...)

"int $0x80;"

...調用syscall。

"movl %%eax,%0"

... syscalls以%eax返回結果; %0表示約束中提到的第一項。

: "=m" (__res) //from here can't understand

...“ constraints”告訴gcc它可以將內聯匯編塊使用和產生的輸入和輸出值放在哪里。 第一部分(在第一個: )用於輸出。 這里的"=m"表示__res應該保留在內存中( "m" ),並且它是只寫的,即任何先前的值都將被覆蓋( "=" )。 約束中的操作數可以用內聯匯編塊中的數字表示(例如%0 ),從0開始第一個出現。

: "m" (a), "m" (b) , "m" (c)

...下一部分用於輸入。 這表示它們都將被放置在內存中。

: "%eax","%ebx","%ecx", "%edx",

...這最后一部分指示“混亂的”寄存器,即,由於內聯匯編塊中的代碼而將被覆蓋的寄存器。 GCC會將內聯匯編器塊放入它生成的其他代碼的中間,但是它不知道該塊中的指令實際上是做什么的-因此,您必須告訴它在該寄存器之前可能存在於那些寄存器中的任何值。此后該屏蔽將不再有效。

);

該函數正在執行系統調用(由於x86 int 0x80 )。

您標記的部分是GCC內聯匯編器幫助程序-允許GCC將占位符(%0-%3)更改為C名稱給定的實際值,本例中為__res, a, b, c

您可以在此處了解確切的內聯匯編器語法:

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

您可以在此處找到有關gcc內聯匯編語法的所有所需信息:

http://www.ibm.com/developerworks/linux/library/l-ia.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM