本文對內嵌彙編語法,從基本語法、內嵌彙編的格式介紹、和擴充套件的內嵌彙編格式進行了詳細說明,需要說明的是gcc採用的是at&t的彙編格式.
一 基本語法
語法上主要有以下幾個不同.
★ 暫存器命名原則
at&t: %eax intel: eax
★ 源/目的運算元順序
at&t: movl %eax,%ebx intel: mov ebx,eax
★常數/立即數的格式
at&t: movl $_value,%ebx intel: mov eax,_value
把_value的位址放入eax暫存器
at&t: movl $0xd00d,%ebx intel: mov ebx,0xd00d
★ 運算元長度標識
at&t: movw %ax,%bx intel: mov bx,ax
★定址方式
at&t: immed32(basepointer,indexpointer,indexscale)
intel: [basepointer indexpointer*indexscale imm32)
linux工作於保護模式下,用的是32位線性位址,所以在計算位址時不用考慮segment:offset的問題.上式中的位址應為:
imm32 basepointer indexpointer*indexscale
下面是一些例子:
★直接定址
at&t: _booga ;
_booga是乙個全域性的c變數注意加上$是表示位址引用,不加是表示值引用.
注:對於區域性變數,可以通過堆疊指標引用.
intel: [_booga]
★暫存器間接定址
at&t: (%eax)
intel: [eax]
★變址定址
at&t: _variable(%eax)
intel: [eax _variable]
at&t: _array(,%eax,4)
intel: [eax*4 _array]
at&t: _array(%ebx,%eax,8)
intel: [ebx eax*8 _array]
二 基本的內嵌彙編
基本的內嵌彙編很簡單,一般是按照下面的格式
a**(statements);
例如:a**(nop); a**(cli);
a** 和 __a**__是完全一樣的.
如果有多行彙編,則每一行都要加上 nt例如:
a**( pushl %eaxnt
movl $0,%eaxnt
popl %eax);
實際上gcc在處理彙編時,是要把a**(...)的內容列印到彙編檔案中,所以格式控制字元是必要的.再例如:
a**(movl %eax,%ebx);
a**(xorl %ebx,%edx);
a**(movl $0,_booga);
在上面的例子中,由於我們在行內彙編中改變了edx和ebx的值,但是由於gcc的特殊的處理方法,即先形成彙編檔案,再交給gas去彙編,所以gas並不知道我們已經改變了edx和ebx的值,如果程式的上下文需要edx或ebx作暫存,這樣就會引起嚴重的後果.對於變數_booga也存在一樣的問題.為了解決這個問題,就要用到擴充套件的行內彙編語法.
下面可以來解釋letter 4854-4855的問題:
1、變數加下劃線和雙下劃線有什麼特殊含義嗎?加下劃線是指全域性變數,但我的gcc中加不加都無所謂.
2、以上定義用如下呼叫時展開會是什麼意思?
#define _syscall1(type,name,type1,arg1)
type name(type1 arg1)
Gcc使用的內嵌彙編語法格式小教程
本文對內嵌彙編語法,從基本語法 內嵌彙編的格式介紹 和擴充套件的內嵌彙編格式進行了詳細說明,需要說明的是gcc採用的是at t的彙編格式 一 基本語法 語法上主要有以下幾個不同.暫存器命名原則 at t eax intel eax 源 目的運算元順序 at t movl eax,ebx intel ...
GCC內嵌彙編語法
內嵌彙編語法如下 asm 彙編語句模板 輸出部分 輸入部分 破壞描述部分 共四個部分 彙編語句模板,輸出部分,輸入部分,破壞描述部分,各部分使用 格開,彙編語句模板必不可少,其他三部分可選,如果使用了後面的部分,而前面部分為空,也需要用 格開,相應部分內容為空。例如 asm volatile cli...
有關GCC內嵌彙編的總結
在gcc中共包括兩種方法嵌入彙編,分別是 基本內聯彙編語句 basic inline asm statement 和擴充套件內聯彙編語句 extended inline asm statement 基本內聯彙編不包括運算元 operand 而擴充套件內聯彙編語句乙個或多個運算元 operands 先...