AT&T指令集
GAS中每個(gè)操作都是有一個(gè)字符的后綴,表明操作數(shù)的大小。
C聲明 |
GAS后綴 |
大小(字節(jié)) |
char |
b |
1 |
short |
w |
2 |
(unsigned) int / long / char* |
l |
4 |
float |
s |
4 |
double |
l |
8 |
long double |
t |
10/12 |
注意:GAL使用后綴“l”同時(shí)表示4字節(jié)整數(shù)和8字節(jié)雙精度浮點(diǎn)數(shù),這不會(huì)產(chǎn)生歧義因?yàn)楦↑c(diǎn)數(shù)使用的是完全不同的指令和寄存器。
操作數(shù)格式:
格式 |
操作數(shù)值 |
名稱(chēng) |
樣例(GAS = C語(yǔ)言) |
$Imm |
Imm |
立即數(shù)尋址 |
$1 = 1 |
Ea |
R[Ea] |
寄存器尋址 |
%eax = eax |
Imm |
M[Imm] |
絕對(duì)尋址 |
0x104 = *0x104 |
(Ea) |
M[R[Ea]] |
間接尋址 |
(%eax)= *eax |
Imm(Ea) |
M[Imm+R[Ea]] |
(基址+偏移量)尋址 |
4(%eax) = *(4+eax) |
(Ea,Eb) |
M[R[Ea]+R[Eb]] |
變址 |
(%eax,%ebx) = *(eax+ebx) |
Imm(Ea,Eb) |
M[Imm+R[Ea]+R[Eb]] |
尋址 |
9(%eax,%ebx)= *(9+eax+ebx) |
(,Ea,s) |
M[R[Ea]*s] |
伸縮化變址尋址 |
(,%eax,4)= *(eax*4) |
Imm(,Ea,s) |
M[Imm+R[Ea]*s] |
伸縮化變址尋址 |
0xfc(,%eax,4)= *(0xfc+eax*4) |
(Ea,Eb,s) |
M(R[Ea]+R[Eb]*s) |
伸縮化變址尋址 |
(%eax,%ebx,4) = *(eax+ebx*4) |
Imm(Ea,Eb,s) |
M(Imm+R[Ea]+R[Eb]*s) |
伸縮化變址尋址 |
8(%eax,%ebx,4) = *(8+eax+ebx*4) |
注:M[xx]表示在存儲(chǔ)器中xx地址的值,R[xx]表示寄存器xx的值,這種表示方法將寄存器、內(nèi)存都看出一個(gè)大數(shù)組的形式。
數(shù)據(jù)傳送指令:
指令 |
效果 |
描述 |
movl S,D |
D <-- S |
傳雙字 |
movw S,D |
D <-- S |
傳字 |
movb S,D |
D <-- S |
傳字節(jié) |
movsbl S,D |
D <-- 符號(hào)擴(kuò)展S |
符號(hào)位填充(字節(jié)->雙字) |
movzbl S,D |
D <-- 零擴(kuò)展S |
零填充(字節(jié)->雙字) |
pushl S |
R[%esp] <-- R[%esp] – 4; M[R[%esp]] <-- S |
壓棧 |
popl D |
D <-- M[R[%esp]]; R[%esp] <-- R[%esp] + 4; |
出棧 |
注:均假設(shè)棧往低地址擴(kuò)展。
算數(shù)和邏輯操作地址:
指令 |
效果 |
描述 |
leal S,D |
D = &S |
movl地版,S地址入D,D僅能是寄存器 |
incl D |
D++ |
加1 |
decl D |
D-- |
減1 |
negl D |
D = -D |
取負(fù) |
notl D |
D = ~D |
取反 |
addl S,D |
D = D + S |
加 |
subl S,D |
D = D – S |
減 |
imull S,D |
D = D*S |
乘 |
xorl S,D |
D = D ^ S |
異或 |
orl S,D |
D = D | S |
或 |
andl S,D |
D = D & S |
與 |
sall k,D |
D = D << k |
左移 |
shll k,D |
D = D << k |
左移(同sall) |
sarl k,D |
D = D >> k |
算數(shù)右移 |
shrl k,D |
D = D >> k |
邏輯右移 |
特殊算術(shù)操作:
指令 |
效果 |
描述 |
imull S |
R[%edx]:R[%eax] = S * R[%eax] |
無(wú)符號(hào)64位乘 |
mull S |
R[%edx]:R[%eax] = S * R[%eax] |
有符號(hào)64位乘 |
cltd S |
R[%edx]:R[%eax] = 符號(hào)位擴(kuò)展R[%eax] |
轉(zhuǎn)換為4字節(jié) |
idivl S |
R[%edx] = R[%edx]:R[%eax] % S; R[%eax] = R[%edx]:R[%eax] / S; |
有符號(hào)除法,保存余數(shù)和商 |
divl S |
R[%edx] = R[%edx]:R[%eax] % S; R[%eax] = R[%edx]:R[%eax] / S; |
無(wú)符號(hào)除法,保存余數(shù)和商 |
注:64位數(shù)通常存儲(chǔ)為,高32位放在edx,低32位放在eax。
條件碼:
條件碼寄存器描述了最近的算數(shù)或邏輯操作的屬性。
CF:進(jìn)位標(biāo)志,最高位產(chǎn)生了進(jìn)位,可用于檢查無(wú)符號(hào)數(shù)溢出。
OF:溢出標(biāo)志,二進(jìn)制補(bǔ)碼溢出——正溢出或負(fù)溢出。
ZF:零標(biāo)志,結(jié)果為0。
SF:符號(hào)標(biāo)志,操作結(jié)果為負(fù)。
比較指令:
指令 |
基于 |
描述 |
cmpb S2,S1 |
S1 – S2 |
比較字節(jié),差關(guān)系 |
testb S2,S1 |
S1 & S2 |
測(cè)試字節(jié),與關(guān)系 |
cmpw S2,S1 |
S1 – S2 |
比較字,差關(guān)系 |
testw S2,S1 |
S1 & S2 |
測(cè)試字,與關(guān)系 |
cmpl S2,S1 |
S1 – S2 |
比較雙字,差關(guān)系 |
testl S2,S1 |
S1 & S2 |
測(cè)試雙字,與關(guān)系 |
訪問(wèn)條件碼指令:
指令 |
同義名 |
效果 |
設(shè)置條件 |
sete D |
setz |
D = ZF |
相等/零 |
setne D |
setnz |
D = ~ZF |
不等/非零 |
sets D |
|
D = SF |
負(fù)數(shù) |
setns D |
|
D = ~SF |
非負(fù)數(shù) |
setg D |
setnle |
D = ~(SF ^OF) & ZF |
大于(有符號(hào)>) |
setge D |
setnl |
D = ~(SF ^OF) |
小于等于(有符號(hào)>=) |
setl D |
setnge |
D = SF ^ OF |
小于(有符號(hào)<) |
setle D |
setng |
D = (SF ^ OF) | ZF |
小于等于(有符號(hào)<=) |
seta D |
setnbe |
D = ~CF & ~ZF |
超過(guò)(無(wú)符號(hào)>) |
setae D |
setnb |
D = ~CF |
超過(guò)或等于(無(wú)符號(hào)>=) |
setb D |
setnae |
D = CF |
低于(無(wú)符號(hào)<) |
setbe D |
setna |
D = CF | ZF |
低于或等于(無(wú)符號(hào)<=) |
跳轉(zhuǎn)指令:
指令 |
同義名 |
跳轉(zhuǎn)條件 |
描述 |
jmp Label |
|
1 |
直接跳轉(zhuǎn) |
jmp *Operand |
|
1 |
間接跳轉(zhuǎn) |
je Label |
jz |
ZF |
等于/零 |
jne Label |
jnz |
~ZF |
不等/非零 |
js Label |
|
SF |
負(fù)數(shù) |
jnz Label |
|
~SF |
非負(fù)數(shù) |
jg Label |
jnle |
~(SF^OF) & ~ZF |
大于(有符號(hào)>) |
jge Label |
jnl |
~(SF ^ OF) |
大于等于(有符號(hào)>=) |
jl Label |
jnge |
SF ^ OF |
小于(有符號(hào)<) |
jle Label |
jng |
(SF ^ OF) | ZF |
小于等于(有符號(hào)<=) |
ja Label |
jnbe |
~CF & ~ZF |
超過(guò)(無(wú)符號(hào)>) |
jae Label |
jnb |
~CF |
超過(guò)或等于(無(wú)符號(hào)>=) |
jb Label |
jnae |
CF |
低于(無(wú)符號(hào)<) |
jbe Label |
jna |
CF | ZF |
低于或等于(無(wú)符號(hào)<=) |
轉(zhuǎn)移控制指令:(函數(shù)調(diào)用):
指令 |
描述 |
call Label |
過(guò)程調(diào)用,返回地址入棧,跳轉(zhuǎn)到調(diào)用過(guò)程起始處,返回地址是call后面那條指令的地址 |
call *Operand |
|
leave |
為返回準(zhǔn)備好棧,為ret準(zhǔn)備好棧,主要是彈出函數(shù)內(nèi)的棧使用及%ebp |
用GCC在C中潛入?yún)R編代碼:
asm( code-string [:output-list [ : input-list [ :overwrite-list]]]);
注意,后面的參數(shù)(如overwrite-list)如果為空則不要相應(yīng)的“:”,而如果前面參數(shù)(如output-list)為空則需要用“:”占位。
如:
asm ("..."
: //output需要占位
: "r" (src) //后面的Overwrites不能寫(xiě),我測(cè)試的結(jié)果是寫(xiě)了編譯不過(guò)
};
如:
Int ok_umul(unsigned x,unsigned y,unsigned *dest)
{
int result;
asm(“movl %2 , %%eax; mull %3; movl %%eax,%0;\
setae %dl; movzbl %%dl,%1”
: “=r” (*dest) , “=r” (result) //output
: “r” (x) , “r” (y) //inputs
: “%ebx” , “%edx” //Overwrites
);
return result;
}
我們用%0--%n表示輸入的參數(shù),從前往后統(tǒng)一編號(hào)(如上例中*dest表示%0,reset是%1,x是%2,y是%3),”r”表示整數(shù)寄存器,”=”表示對(duì)其進(jìn)行了賦值。%eax要寫(xiě)成%%eax,這是c語(yǔ)言字符串的規(guī)則,別忘了code-string就是一個(gè)c語(yǔ)言的字符串。
posted on 2009-12-08 15:48 ChinaPanda 閱讀(1898) 評(píng)論(1) 編輯 收藏 引用