《汇编》常用指令详解
GAS中每个操作都是有一个字符的后缀,表明操作数的大小。C声明GAS后缀大小(字节)
charb1
shortw2
(unsigned) int / long / char*l4
floats4
doublel8
long doublet10/12
注意:GAL使用后缀“l”同时表示4字节整数和8字节双精度浮点数,这不会产生歧义因为浮点数使用的是完全不同的指令和寄存器。
操作数格式:
格式操作数值名称样例(GAS = C语言)
$ImmImm立即数寻址$1 = 1
EaR寄存器寻址%eax = eax
ImmM绝对寻址0x104 = *0x104
(Ea)M]间接寻址(%eax)= *eax
Imm(Ea)M](基址+偏移量)寻址4(%eax) = *(4+eax)
(Ea,Eb)M+R]变址(%eax,%ebx) = *(eax+ebx)
Imm(Ea,Eb)M+R]寻址9(%eax,%ebx)= *(9+eax+ebx)
(,Ea,s)M*s]伸缩化变址寻址(,%eax,4)= *(eax*4)
Imm(,Ea,s)M*s]伸缩化变址寻址0xfc(,%eax,4)= *(0xfc+eax*4)
(Ea,Eb,s)M(R+R*s)伸缩化变址寻址(%eax,%ebx,4) = *(eax+ebx*4)
Imm(Ea,Eb,s)M(Imm+R+R*s)伸缩化变址寻址8(%eax,%ebx,4) = *(8+eax+ebx*4)
注:M表示在存储器中xx地址的值,R表示寄存器xx的值,这种表示方法将寄存器、内存都看出一个大数组的形式。
数据传送指令:
指令效果描述
movl S,DD <-- S传双字
movw S,DD <-- S传字
movb S,DD <-- S传字节
movsbl S,DD <-- 符号扩展S符号位填充(字节->双字)
movzbl S,DD <-- 零扩展S零填充(字节->双字)
pushl SR[%esp] <-- R[%esp] – 4;M] <-- S压栈
popl DD <-- M];R[%esp] <-- R[%esp] + 4;出栈
注:均假设栈往低地址扩展。
算数和逻辑操作地址:
指令效果描述
leal S,DD = &Smovl地版,S地址入D,D仅能是寄存器
incl DD++加1
decl DD--减1
negl DD = -D取负
notl DD = ~D取反
addl S,DD = D + S加
subl S,DD = D – S减
imull S,DD = D*S乘
xorl S,DD = D ^ S异或
orl S,DD = D | S或
andl S,DD = D & S与
sall k,DD = D << k左移
shll k,DD = D << k左移(同sall)
sarl k,DD = D >> k算数右移
shrl k,DD = D >> k逻辑右移
特殊算术操作:
指令效果描述
imull SR[%edx]:R[%eax] = S * R[%eax]无符号64位乘
mull SR[%edx]:R[%eax] = S * R[%eax]有符号64位乘
cltd SR[%edx]:R[%eax] = 符号位扩展R[%eax]转换为4字节
idivl SR[%edx] = R[%edx]:R[%eax] % S;R[%eax] = R[%edx]:R[%eax] / S;有符号除法,保存余数和商
divl SR[%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,S1S1 – S2比较字节,差关系
testb S2,S1S1 & S2测试字节,与关系
cmpw S2,S1S1 – S2比较字,差关系
testw S2,S1S1 & S2测试字,与关系
cmpl S2,S1S1 – S2比较双字,差关系
testl S2,S1S1 & S2测试双字,与关系
访问条件码指令:
指令同义名效果设置条件
sete DsetzD = ZF相等/零
setne DsetnzD = ~ZF不等/非零
sets D
D = SF负数
setns D
D = ~SF非负数
setg DsetnleD = ~(SF ^OF) & ZF大于(有符号>)
setge DsetnlD = ~(SF ^OF)小于等于(有符号>=)
setl DsetngeD = SF ^ OF小于(有符号<)
setle DsetngD = (SF ^ OF) | ZF小于等于(有符号<=)
seta DsetnbeD = ~CF & ~ZF超过(无符号>)
setae DsetnbD = ~CF超过或等于(无符号>=)
setb DsetnaeD = CF低于(无符号<)
setbe DsetnaD = CF | ZF低于或等于(无符号<=)
跳转指令:
指令同义名跳转条件描述
jmp Label
1直接跳转
jmp *Operand
1间接跳转
je LabeljzZF等于/零
jne Labeljnz~ZF不等/非零
js Label
SF负数
jnz Label
~SF非负数
jg Labeljnle~(SF^OF) & ~ZF大于(有符号>)
jge Labeljnl~(SF ^ OF)大于等于(有符号>=)
jl LabeljngeSF ^ OF小于(有符号<)
jle Labeljng(SF ^ OF) | ZF小于等于(有符号<=)
ja Labeljnbe~CF & ~ZF超过(无符号>)
jae Labeljnb~CF超过或等于(无符号>=)
jb LabeljnaeCF低于(无符号<)
jbe LabeljnaCF | ZF低于或等于(无符号<=)
转移控制指令:(函数调用):
指令描述
call Label过程调用,返回地址入栈,跳转到调用过程起始处,返回地址是call后面那条指令的地址
call *Operand
leave为返回准备好栈,为ret准备好栈,主要是弹出函数内的栈使用及%ebp
新手必须会的代码,好好记记! 满满的感谢。 收藏,以后再慢慢学! 我也收藏了 先收藏,有时间学习一下 收藏了 感谢分享 我是来学习的 我是来学习的 新手学习中,谢谢分享了