您的位置:首页 > 其它

at&t汇编语言

2008-03-07 11:31 260 查看
编辑

GAS中每个操作都是有一个字符的后缀,表明操作数的大小。
[align=center]C声明[/align]
[align=center]GAS后缀[/align]
[align=center]大小(字节)[/align]
[align=center]char[/align]
[align=center]b[/align]
[align=center]1[/align]
[align=center]short[/align]
[align=center]w[/align]
[align=center]2[/align]
[align=center](unsigned) int / long / char* [/align]
[align=center]l[/align]
[align=center]4[/align]
[align=center]float[/align]
[align=center]s[/align]
[align=center]4[/align]
[align=center]double[/align]
[align=center]l[/align]
[align=center]8[/align]
[align=center]long double[/align]
[align=center]t[/align]
[align=center]10/12[/align]
注意:GAL使用后缀“l”同时表示4字节整数和8字节双精度浮点数,这不会产生歧义因为浮点数使用的是完全不同的指令和寄存器。

操作数格式:
[align=center]格式[/align]
[align=center]操作数值[/align]
[align=center]名称[/align]
[align=center]样例(GAS = C语言)[/align]
[align=center]$Imm[/align]
[align=center]Imm[/align]
[align=center]立即数寻址[/align]
[align=center]$1 = 1[/align]
[align=center]Ea[/align]
[align=center]R[Ea][/align]
[align=center]寄存器寻址[/align]
[align=center]%eax = eax[/align]
[align=center]Imm[/align]
[align=center]M[Imm][/align]
[align=center]绝对寻址[/align]
[align=center]0x104 = *0x104[/align]
[align=center](Ea)[/align]
[align=center]M[R[Ea]][/align]
[align=center]间接寻址[/align]
[align=center](%eax)= *eax[/align]
[align=center]Imm(Ea)[/align]
[align=center]M[Imm+R[Ea]][/align]
[align=center](基址+偏移量)寻址[/align]
[align=center]4(%eax) = *(4+eax)[/align]
[align=center](Ea,Eb)[/align]
[align=center]M[R[Ea]+R[Eb]][/align]
[align=center]变址[/align]
[align=center](%eax,%ebx) = *(eax+ebx)[/align]
[align=center]Imm(Ea,Eb)[/align]
[align=center]M[Imm+R[Ea]+R[Eb]][/align]
[align=center]寻址[/align]
[align=center]9(%eax,%ebx)= *(9+eax+ebx)[/align]
[align=center](,Ea,s)[/align]
[align=center]M[R[Ea]*s][/align]
[align=center]伸缩化变址寻址[/align]
[align=center](,%eax,4)= *(eax*4)[/align]
[align=center]Imm(,Ea,s)[/align]
[align=center]M[Imm+R[Ea]*s][/align]
[align=center]伸缩化变址寻址[/align]
[align=center]0xfc(,%eax,4)= *(0xfc+eax*4)[/align]
[align=center](Ea,Eb,s)[/align]
[align=center]M(R[Ea]+R[Eb]*s)[/align]
[align=center]伸缩化变址寻址[/align]
[align=center](%eax,%ebx,4) = *(eax+ebx*4)[/align]
[align=center]Imm(Ea,Eb,s)[/align]
[align=center]M(Imm+R[Ea]+R[Eb]*s)[/align]
[align=center]伸缩化变址寻址[/align]
[align=center]8(%eax,%ebx,4) = *(8+eax+ebx*4)[/align]
注:M[xx]表示在存储器中xx地址的值,R[xx]表示寄存器xx的值,这种表示方法将寄存器、内存都看出一个大数组的形式。

数据传送指令:
指令
效果
描述
movl S,D
D <-- S
传双字
movw S,D
D <-- S
传字
movb S,D
D <-- S
传字节
movsbl S,D
D <-- 符号扩展S
符号位填充(字节->双字)
movzbl S,D
D <-- 零扩展S
零填充(字节->双字)
pushl S
R[%esp] <-- R[%esp] – 4;
M[R[%esp]] <-- S
压栈
popl D
D <-- M[R[%esp]];
R[%esp] <-- R[%esp] + 4;
出栈
注:均假设栈往低地址扩展。

算数和逻辑操作地址:
指令
效果
描述
leal S,D
D = &S
movl地版,S地址入D,D仅能是寄存器
incl D
D++
加1
decl D
D--
减1
negl D
D = -D
取负
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
算数右移
shrl k,D
D = D >> k
逻辑右移
特殊算术操作:
指令
效果
描述
imull S
R[%edx]:R[%eax] = S * R[%eax]
无符号64位乘
mull S
R[%edx]:R[%eax] = S * R[%eax]
有符号64位乘
cltd S
R[%edx]:R[%eax] = 符号位扩展R[%eax]
转换为4字节
idivl S
R[%edx] = R[%edx]:R[%eax] % S;
R[%eax] = R[%edx]:R[%eax] / S;
有符号除法,保存余数和商
divl S
R[%edx] = R[%edx]:R[%eax] % S;
R[%eax] = R[%edx]:R[%eax] / S;
无符号除法,保存余数和商
注:64位数通常存储为,高32位放在edx,低32位放在eax。

条件码:
条件码寄存器描述了最近的算数或逻辑操作的属性。
CF:进位标志,最高位产生了进位,可用于检查无符号数溢出。
OF:溢出标志,二进制补码溢出——正溢出或负溢出。
ZF:零标志,结果为0。
SF:符号标志,操作结果为负。

比较指令:
指令
基于
描述
cmpb S2,S1
S1 – S2
比较字节,差关系
testb S2,S1
S1 & S2
测试字节,与关系
cmpw S2,S1
S1 – S2
比较字,差关系
testw S2,S1
S1 & S2
测试字,与关系
cmpl S2,S1
S1 – S2
比较双字,差关系
testl S2,S1
S1 & S2
测试双字,与关系
访问条件码指令:
指令
同义名
效果
设置条件
sete D
setz
D = ZF
相等/零
setne D
setnz
D = ~ZF
不等/非零
sets D
D = SF
负数
setns D
D = ~SF
非负数
setg D
setnle
D = ~(SF ^OF) & ZF
大于(有符号>)
setge D
setnl
D = ~(SF ^OF)
小于等于(有符号>=)
setl D
setnge
D = SF ^ OF
小于(有符号<)
setle D
setng
D = (SF ^ OF) | ZF
小于等于(有符号<=)
seta D
setnbe
D = ~CF & ~ZF
超过(无符号>)
setae D
setnb
D = ~CF
超过或等于(无符号>=)
setb D
setnae
D = CF
低于(无符号<)
setbe D
setna
D = CF | ZF
低于或等于(无符号<=)
跳转指令:
指令
同义名
跳转条件
描述
jmp Label
1
直接跳转
jmp *Operand
1
间接跳转
je Label
jz
ZF
等于/零
jne Label
jnz
~ZF
不等/非零
js Label
SF
负数
jnz Label
~SF
非负数
jg Label
jnle
~(SF^OF) & ~ZF
大于(有符号>)
jge Label
jnl
~(SF ^ OF)
大于等于(有符号>=)
jl Label
jnge
SF ^ OF
小于(有符号<)
jle Label
jng
(SF ^ OF) | ZF
小于等于(有符号<=)
ja Label
jnbe
~CF & ~ZF
超过(无符号>)
jae Label
jnb
~CF
超过或等于(无符号>=)
jb Label
jnae
CF
低于(无符号<)
jbe Label
jna
CF | ZF
低于或等于(无符号<=)
转移控制指令:(函数调用):
指令
描述
call Label
过程调用,返回地址入栈,跳转到调用过程起始处,返回地址是call后面那条指令的地址
call *Operand
leave
为返回准备好栈,为ret准备好栈,主要是弹出函数内的栈使用及%ebp
用GCC在C中潜入汇编代码:
asm( code-string [:output-list [ : input-list [ :overwrite-list]]]);
注意,后面的参数(如overwrite-list)如果为空则不要相应的“:”,而如果前面参数(如output-list)为空则需要用“:”占位。
如:
asm ("..."
: //output需要占位

: "r" (src) //后面的Overwrites不能写,我测试的结果是写了编译不过
};

如:
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表示输入的参数,从前往后统一编号(如上例中*dest表示%0,reset是%1,x是%2,y是%3),”r”表示整数寄存器,”=”表示对其进行了赋值。%eax要写成%%eax,这是c语言字符串的规则,别忘了code-string就是一个c语言的字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: