複製鏈接
請複製以下鏈接發送給好友

內聯彙編

鎖定
內聯彙編,指在C語言中插入彙編語言,其是Linux中使用的基本彙編程序語法。
中文名
內聯彙編
解    釋
在C語言中可以插入彙編語言
GNU 彙編簡述
Linux 中使用的基本彙編程序語法
寄存器命名
寄存器名稱有 % 前綴
操作數大小
字節 ,字 ,長型 。
立即操作數
通過使用 $ 指定直接操作數

內聯彙編名詞概念

在C語言中可以插入彙編語言。

內聯彙編彙編語法

Linux 中使用的基本彙編程序語法。GCC(用於 Linux 的 GNU C 編譯器)使用 AT&T 彙編語法。下面列出了這種語法的一些基本規則。

內聯彙編寄存器命名

寄存器名稱有 % 前綴。即,如果必須使用 eax,它應該用作 %eax。

內聯彙編操作數的順序

在所有指令中,先是源操作數,然後才是目的操作數。這與將源操作數放在目的操作數之後的 Intel 語法不同。
mov %eax, %ebx, transfers the contents of eax to ebx.

內聯彙編操作數大小

根據操作數是字節 (byte)、字 (word) 還是長型 (long),指令的後綴可以是 b、w 或 l。這並不是強制性的;GCC 會嘗試通過讀取操作數來提供相應的後綴。但手工指定後綴可以改善代碼的可讀性,並可以消除編譯器猜測不正確的可能性。
movb %al, %bl -- Byte move movw %ax, %bx -- Word move movl %eax, %ebx -- Longword move

內聯彙編立即操作數

通過使用 $ 指定直接操作數。
movl $0xffff, %eax -- will move the value of 0xffff into eax register.

內聯彙編間接內存引用

任何對內存的間接引用都是通過使用 ( ) 來完成的。
movb (%esi), %al -- will transfer the byte in the memory pointed by esi into alregister

內聯彙編特殊結構

GCC 為內聯彙編提供特殊結構,它具有以下格式:
GCG 的 "asm" 結構
asm assembler template
: output operands (optional)
: input operands (optional)
: list of clobbered registers
(optional);
本例中,彙編程序模板由彙編指令組成。輸入操作數是充當指令輸入操作數使用的 C 表達式。輸出操作數是將對其執行彙編指令輸出的 C 表達式
內聯彙編的重要性體現在它能夠靈活操作,而且可以使其輸出通過 C 變量顯示出來。因為它具有這種能力,所以 "asm" 可以用作彙編指令和包含它的 C 程序之間的接口。
一個非常基本但很重要的區別在於 簡單內聯彙編只包括指令,而 擴展內聯彙編包括操作數。要説明這一點,考慮以下示例:
內聯彙編的基本要素
{ int a=10, b; asm ("movl %1, %%eax; movl %%eax, %0;" :"=r"(b) /* output */ :"r"(a) /* input */ :"%eax"); /* clobbered register */}
在上例中,我們使用匯編指令使 "b" 的值等於 "a"。請注意以下幾點:
內聯彙編 內聯彙編
"b" 是輸出操作數,由 %0 引用,"a" 是輸入操作數,由 %1 引用。 "r" 是操作數的約束,它指定將變量 "a" 和 "b" 存儲在寄存器中。請注意,輸出操作數約束應該帶有一個約束脩飾符 "=",指定它是輸出操作數。 要在 "asm" 內使用寄存器 %eax,%eax 的前面應該再加一個 %,換句話説就是 %%eax,因為 "asm" 使用 %0、%1 等來標識變量。任何帶有一個 % 的數都看作是輸入/輸出操作數,而不認為是寄存器。 第三個冒號後的修飾寄存器 %eax 告訴將在 "asm" 中修改 GCC %eax 的值,這樣 GCC 就不使用該寄存器存儲任何其它的值。 movl %1, %%eax 將 "a" 的值移到 %eax 中, movl %%eax, %0 將 %eax 的內容移到 "b" 中。 因為 "b" 被指定成輸出操作數,因此當 "asm" 的執行完成後,它將反映出更新的值。換句話説,對 "asm" 內 "b" 所做的更改將在 "asm" 外反映出來。