要宣告和使用內聯彙編函式,應當使用關鍵字asm。內聯彙編能夠操作c語言變數並使其輸出可見,因此,asm關鍵字可以看做彙編指令和包含它的c程式之間的介面。
gcc內聯函式使用at&t彙編語法,這是我們常見彙編**的語法格式,有以下幾個特點:
1. 運算元方向:第乙個運算元是源,第二個運算元是目標。
2. 暫存器命名:暫存器名稱的字首是%e,例如要使用eax,就寫%eax。
3. 立即數:c語言程式中的常量(常數),在組合語言中是乙個以$開頭的運算元。
4. 運算元大小:at&t語法中,記憶體運算元的大小由操作指令的最後乙個字元決定。以「b」,「w」和「l」為字尾的操作指令分別指定位元組(8位),字(16位),字長(32位)的暫存器引用。
5. 記憶體運算元:at&t語法中,間接記憶體引用通常的形式為:disp(base,index,scale)。
單行內聯函式:asm(「內聯指令」)
asm("movl %ecx
%eax");
_asm_("movl %ecx
%eax");
說明:asm和asm都是合法形式:當asm與程式中某些變數重名時使用後者。多行內聯函式:asm(「第一條內聯指令\n\t」「第二條內聯指令\n\t」「最後一條內聯指令」)
asm("movl %eax, %ebx\n\t"
"movl $56, %esi\n\t"
"movl %ecx, $label(%edx,%ebx,$4)\n\t"
"movb %ah, (%ebx)");
基本內聯彙編中只有指令,擴充套件彙編中可以指定運算元。
asm ( assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
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」是運算元的乙個約束。稍後我們會看到約束條件。目前,「r」表示gcc使用任何暫存器來儲存運算元。輸出運算元約束應該有乙個約束修飾符「=」。這個修飾符說,它是輸出運算元,是只寫的。
- 在暫存器名稱前面有兩個%的字首。這有助於gcc區分運算元和暫存器。運算元只有乙個%作為字首。
- 第三個冒號後的破折號暫存器%eax告訴gcc%eax的值在「asm」內被修改,所以gcc不會使用這個暫存器來儲存任何其他的值。
- 當「asm」執行完成時,「b」將反映更新值,因為它被指定為輸出運算元。換句話說,「asm」內部對「b」所做的改變應該反映在「asm」之外。
運算元的一般形式:
「約束」(c表示式)
在匯程式設計序模板中,每個運算元都由數字引用,編號規則如下:如果總共有n個運算元(包括輸入和輸出),則第乙個輸出運算元編號為0,按遞增順序繼續,最後乙個輸入運算元編號為n-1。暫存器運算元約束(r) r輸出運算元表示式必須是左值。輸入運算元不像這樣受限制。
registers
a%eax, %ax, %al
b%ebx, %bx, %bl
c%ecx, %cx, %cl
d%edx, %dx, %dl
s%esi, %si
d%edi, %di
記憶體運算元約束(m)
如果c變數需要在「asm」內部更新,並且你不想用暫存器來儲存它的值,那麼記憶體約束可以被最有效的使用。例如,idtr的值儲存在記憶體位
asm("sidt %0\n" : :"m"(loc));
匹配約束
這種約束在以下兩種情況下使用:
- 從變數讀取輸入或者變數被修改並且修改被寫回到相同變數。
- 不需要單獨的輸入和輸出運算元例項。
例:
asm ("incl %0" :"=a"(var):"0"(var));
約束修飾符
約束修飾符用於更精準地控制約束地影響,常用的約束修飾符有兩種:
- 「=」:表示該運算元對於該指令是只寫的; 之前的值被丟棄並被輸出資料替代。
- 「&」:表示這個運算元是乙個早期的運算元,它在指令完成之前使用輸入運算元被修改。因此,該運算元可能不在用作輸入運算元或作為任何儲存器位址的一部分的暫存器中。如果輸入運算元僅用作輸入,則在早期結果寫入之前可以將輸入運算元繫結到早期運算元。
彙編 div Solidity內聯彙編
在用solidity開發以太坊智慧型合約時,使用彙編可以直接與evm互動,降低gas開銷成本,更精細的控制智慧型合約的行為,因此值得solidity開發者學習並加以利用。本文是solidity彙編開發的簡明教程,旨在幫助你快速熟悉如何在solidity智慧型合約 中嵌入彙編 以太坊虛擬機器evm有自...
GCC內聯彙編
有時為了高效,有時為了直接控制硬體,有些模組我們不得不直接用組合語言來編寫,並且對外提供呼叫的介面,隱藏細節,這其實就是內聯彙編。如何使用內聯彙編?我們就以 gcc 為例,一窺其中奧秘!一 關鍵字 如何讓 gcc 知道 中內嵌的彙編呢?借助 關鍵字!來看下面的例子 asm volatile hlt ...
gcc內聯彙編
有時為了高效,有時為了直接控制硬體,有些模組我們不得不直接用組合語言來編寫,並且對外提供呼叫的介面,隱藏細節,這其實就是內聯彙編。如何使用內聯彙編?我們就以 gcc 為例,一窺其中奧秘!一 關鍵字 如何讓 gcc 知道 中內嵌的彙編呢?借助關鍵字!來看下面的例子 a volatile hlt a 表...