80X86指令总结
一、数据传送指令
指令名称 |
汇编语句格式 |
功能 |
影响标志位 |
传送 move data |
mov opd, ops | (ops) → opd;分为主存储器、通用寄存器、段寄存器,不可同时使用主存储器,类型要匹配:byte,word,dword | 无 |
带符号扩充的传送 move with sign-extend |
movsx opd, ops | 将ops的符号向前扩展成与opd相同的数据类型后 → opd ops不能为立即数, |
无 |
带0扩展的传送 move with zero-extend |
movzx opd, ops | 将ops的高位向前补0扩展成与opd相同的数据类型后 → opd | 无 |
数据交换 exchange |
xchg opd, ops | 将(opd)与(ops)交换 源操作数不能是立即操作数 |
无 |
32位寄存器字节交换 byte swap |
bswap reg (reg,代表寄存器,下同) |
将从第一个与第四个字节交换,将第二个字节和第三个字节交换 (按字节反序),32位寄存器 |
无 |
交换并相加 exchange and add |
xadd opd, ops | 将(opd)与(ops)互换,(opd)+(ops) → opd | af,of,pf, sf,zf,cf |
查表转换 table look-up translation |
xlat ops 或 xlatb | (ds:[bx/ebx+al]) → al (求和之前al作无符号扩展), 一般把数表的首地址放到bx/ebx中,lea bx, buf ;al就是在buf中的位置 |
无 |
传送偏移地址 load effective address |
lea reg,ops | ops → reg | 无 |
传送偏移地址和数据段首地址 load data segment register |
lds reg, ops | (ops)→ reg (ops+2/4)→ ds;ops一定是存储器地址,类型为dword/fword |
无 |
传送偏移地址和附加段首地址 load far pointer to extra segment |
les/lfs/lgs reg, ops | 同上,只是段寄存器分别为es,fs,gs | 无 |
传送偏移地址和堆栈首地址 load stack segment |
lss reg, ops | 同上,段寄存器为ss | 无 |
进栈 push word/dword onto stack |
push ops pushw ops 或pushd ops |
16位段:(sp) – 2/4 → sp (ops) → [sp]; 可以为两个字节, 或四个字节32位段:(esp) – 2/4 → esp (ops) → [esp]; 同上 |
无 |
所有16位通用寄存器进栈 pushall 16-bit general registers |
pusha | (sp/esp) –2 → sp/esp 重复8次压入ax,cx,dx,bx,sp(指令执前),bp,si,di;是先改变sp/esp 再把数据写入 | 无 |
所有32位通用寄存器进栈 pushall 32-bit general registers |
pushad | (sp/esp) – 4 → sp/esp 重复8次压入eax,ecx,edx,ebx, esp(指令执行前),ebp,esi,edi;是先改变sp/esp 再把数据写入 |
无 |
出栈 pop a word/dword frome the stack |
pop opd | 16位段:[sp]→ (opd) ; (sp) + 2/4 → sp ;可以为两个字节,或四个字节 32位段:[esp]→ (opd) ; (esp) + 2/4 → esp ; 同上 |
无 |
出栈到所有16位通用寄存器 pop stack into all 16-bit registers |
popa | 将栈顶的16个字节依次出栈到di,si,bp,丢弃2个字节,bx,dx,cx,ax, (sp/esp)+16 → sp/esp |
无 |
出栈到所有32位通用寄存器 pop stack into all 32-bit registers |
popad | 将栈顶的16个字节依次出栈到edi,esi,ebp,丢弃4个字节,ebx,edx,ecx,eax, (sp/esp)+32 → sp/esp |
无 |
标志进栈 push flags onto stack |
pushf | (sp/esp) – 2 → sp/esp (flags) → [sp/esp] |
无 |
扩展标志出栈 push eflags onto stack |
pushfd | sp/esp – 4 → sp/esp (eflags) → [sp/esp] |
无 |
标志出栈 pop stack into flags |
popf | [sp/esp] → flags sp/esp + 4 → sp/esp |
无 |
扩展标志出栈 pop stack into eflags |
popfd | [sp/esp] → eflags sp/esp + 4 → sp/esp |
无 |
标志传送到ah load ah from flags |
lahf | (flags7-0) → ah | 无 |
将ah传送到flags store ah into flags |
sahf | (ah) → flags7-0 | sf,zf,af,pf,cf |
输入 input from port |
in opd, ops | ([ops]) → opd; opd只能是al、ax、eax;ops为立即数(<255)或者dx |
无 |
输出 output to port |
out opd, ops | (ops) → [opd]; ops只能是al、ax、eax;opd为立即数(<255)或者dx |
无 |
二、算术运算指令
指令名称 |
汇编语句格式 |
功能 |
影响标志位 |
加 1 increment |
inc opd | (opd) + 1 → opd | af,of,pf, sf,zf |
加 addition |
add opd, ops | (opd) + (ops) → opd | af,of,pf, sf,zf |
带进位加 add with carry |
adc opd, ops | (opd) + (ops) + cf → opd | af,of,pf, sf,zf |
减 1 decrement |
dec opd | (opd) – 1 → opd | af,of,pf, sf,zf |
求补 two's complement negation |
neg opd | 0 – (opd) → opd | af,of,pf, sf,zf |
减 subtract |
sub opd, ops | (opd) – (ops) → opd | af,of,pf, sf,zf |
带借位减 subtract with borrow |
sbb opd, ops | (opd) – (ops) – cf → opd | af,of,pf, sf,zf |
比较 compare |
cmp opd, ops | (opd) – (ops) 一般用于转移前的控制,应用于跳转 |
af,of,pf, sf,zf |
无符号乘 unsigned multiply |
mul ops | 字节乘:(al) * (ops) → ax; 字乘法:(ax) * (ops) → dx:ax; 双字乘:(eax) * (ops) → edx:eax |
cf,of |
单操作数的有符号乘 signed integer multiply |
imul ops | 字节乘:(al) * (ops) → ax; 字乘法:(ax) * (ops) → dx:ax; 双字乘:(eax) * (ops) → edx:eax |
cf,of |
双操作数的有符号乘 signed integer multiply |
imul opd, ops | (opd) * (ops) → opd;opd可为16/32的寄存器,ops可为同类型的寄存器、存储器或立即数 | cf,of |
三操作数的有符号乘 signed integer multiply |
imul opd, ops, n | (ops) * n → opd;同上,n为立即数 | cf,of |
将字节转换成字 convert byte to word |
cbw | 将al中的符号扩展到ah中,数据的补码数值没有变 | 无 |
将字转换成双字 convert word to double word |
cwd | 将ax中的符号扩展到dx的高位中 | 无 |
将字转换成双字 convert word to double word |
cwde | 将ax中的符号扩展到eax的高位中 | 无 |
将双字转换成4字 convert double word to quadword |
cdq | 将eax中的符号扩展到edx中 | 无 |
无符号除 unsigned divide |
div ops | 字节除:(ax)/(ops)→al(商),ah(余数);字除:(dx:ax)/(ops) → ax(商), dx(余数) 双字除: (edx:eax)/(ops) → eax(商),edx(余数) |
af,of,pf, cf,sf,zf |
有符号除 signed integer divide |
idiv ops | 字节除:(ax)/(ops)→al(商),ah(余数);字除:(dx:ax)/(ops) → ax(商), dx(余数) 双字除: (edx:eax)/(ops) → eax(商),edx(余数) |
af,of,pf, cf,sf,zf |
三、控制转移指令
指令名称 |
汇编语句格式 |
功能 |
影响标志位 |
相等/等于0转移 jump if equal/zero |
je/jz 标号 | zf = 1 转移 | 无 |
不相等/不等于0转移 jump if not equal/zero |
jne/jnz 标号 | zf = 0 转移 | 无 |
为负转移 jump if sign |
js 标号 | sf = 1 转移 | 无 |
为正转移 jump if positive |
jns 标号 | sf = 0 转移 | 无 |
溢出转移 jump if overflow |
jo 标号 | of = 1 转移 | 无 |
无溢出转移 jump if not overflow |
jno 标号 | of = 0 转移 | 无 |
有进位转移 jump if carry |
jc 标号 | cf = 1 转移 | 无 |
无进位转移 jump if not carry |
jnc 标号 | cf = 0 转移 | 无 |
偶检验/偶性转移 jump if parity/parity even |
jp/jpe 标号 | pf = 1 转移 | 无 |
奇检验/奇性转移 jump if no parity/parity odd |
jnp/jpo 标号 | pf = 0 转移 | 无 |
小于/不大于也不等于 转移 jump if less/not greater nor equal |
jl/jnge 标号 | sf ≠ of 转移 | 无 |
不小于/大于或等于转移 jump if not less/greater or equal |
jnl/jge 标号 | sf = of 转移 | 无 |
大于/不小于或不等于转移 jump if greater/not less or not equal |
jg/jnle 标号 | sf = of, 且zf = 0 转移 | 无 |
不大于/小于或等于转移 jump if not greater /less or equal |
jng/jle 标号 | sf ≠ of 或zf = 1 转移 | 无 |
低于/不高于且不等于转移(无符号) jump if below/not above not equal |
jb/jnae 标号 | cf = 1 转移 | 无 |
不低于/高于或等于转移(无符号) jump if now below/above or equal |
jnb/jae 标号 | cf = 0 转移 | 无 |
高于/不低于且比等于转移(无符号) jump if above/not below nor equal |
ja/jnbe 标号 | cf = 0 且 zf = 0 转移 | 无 |
不高于/低于或等于 jump if not above/below or equal |
jna/jbe 标号 | cf = 1 或 zf =1 转移 | 无 |
无条件转移 jump unconditionally |
jmp opd | 相对转移:(opd)+ip/eip → ip/eip 近转移:(opd) → ip/eip 远转移:(opd) → ip/eip, (opd+2/4) → cs,或根据描述符决定 |
无 |
cx为0转移 jump if cx is zero |
jcxz 标号 或jecxz 标号 |
若(cx/ecx) = 0 转移 | 无 |
循环 loop |
loop 标号 或loopw/loopd 标号 |
(cx/ecx) – 1 → cx/ecx, 若(cx/ecx) ≠ 0 则转移 | 无 |
相等/为0循环 loop if equal/zero |
loope/loopz 标号 | (cx/ecx) – 1 → cx/ecx,若(cx/ecx) ≠ 0 且zf = 1 则转移 | 无 |
不相等/不为0循环 loop if not equal/not zero |
loopne/loopnz 标号 | (cx/ecx) – 1 → cx/ecx,若(cx/ecx) ≠ 0 且zf = 0 则转移 | 无 |
检查数组下标边界 check array index against bounds |
bound reg, ops | 若reg的索引值小于ops指定的下边界或大于ops指定的上边界,则变成5号异常 | 无 |
调用子程序 call a procedure |
call opd | 调用opd所指定的子程序(32位段的远调用时,CS被扩展成4字节后压栈) | 任务切换有影响,否则无 |
从子程序返回 return from procedure |
ret [n] n代表16位常量,[]表可选 |
从子程序返回到调用语句的下一个语句处,若n存在,则(sp/esp)+n → sp/esp;32位段远返回时,cs出栈时改变4字节的栈指针 | 无 |
中断调用 interrupt |
int n | (flags/eflags) 入栈,0→if,tf;(cs) 入栈;(4*n)→ip,(4*n+2)→cs或根据idt给eip,cs赋值 | 0→tf,if,返回时复原 |
溢出中断 interrupt if overflow |
into | (flags/eflags) 入栈,0→if,tf;(cs) 入栈;(4*n)→ip,(4*n+2)→cs或根据idt给eip,cs赋值;of=1时产生int 4 | 0→tf,if,返回时复原 |
中断返回 interrupt return |
iret 或iretd(32位段) 或iretf |
ip出栈,cs出栈,flags/eflags出栈,根据nt标志做相应的处理 | 都有影响 |
四、串操作指令
指令名称 |
汇编语句格式 |
功能 |
影响标志位 |
||||||
串传送 move byte/word string |
movs opd, ops movsb,movsw,movsd |
(ds:[si/esi]) → es:[di/edi],(ops所在的段可以取代ds),(si/esi)±1/2/4 → si/esi, (di/edi)±1/2/4 → di/edi | 无 | ||||||
串比较 compare string |
cmps ops, opd cmpsb,compsw,compsd |
(ds:[si/esi]) – (es:[di/edi]),(si/esi)±1/2/4 → si/esi, (di/edi)±1/2/4 →di/edi |
af,cf,of,pf, sf,zf |
||||||
串搜索 scan string |
scas opd scasb,scasw,scasd |
(al/ax/eax) – (es:[di/edi]),(di/edi)±1/2/4 →di/edi | af,cf,of,pf, sf,zf |
||||||
取字符串 load string |
lods ops lodsb, lodsw,lodsd |
(ds:[si/esi]) → al/ax/eax,(ops所在的段可以取代ds), (si/esi)±1/2/4 →si/esi |
无 | ||||||
存字符串 store string |
stos opd stosb,stosw,stosd |
(al/ax/eax)→es:[di/edi],(di/edi)±1/2/4 →di/edi | 无 | ||||||
输入串 input from port to string |
ins opd, dx insb,insw,insd |
([dx]) →es:[di/edi],(di/edi)±1/2/4 →di/edi | 无 | ||||||
输出串 output string port |
outs opd, ops outsb,outsw,outsd |
(ds:[si/esi])→[dx],(si/esi)±1/2/4 →si/esi | 无 | ||||||
重复前缀 repeat string operation |
|
|
无 |
五、位操作指令
指令名称 |
汇编语句格式 |
功能 |
影响标志位 |
求反 one's complement negation |
not opd | ▁▁▁▁▁ (opd)→opd |
无 |
逻辑乘 and |
and opd, ops | (opd)∧(ops)→opd | pf,sf |
位测试 bit test |
bt opd, ops | 将(ops)作为位偏移(0~31)指明的opd对应位的值→CF | cf |
位测试并求补 bit test and complement |
btc opd, ops | 在bt指令的基础上,将opd的对应位求反后→opd | cf |
位测试并清0 bit test and reset |
btr opd, ops | 在bt指令的基础上,将0→opd的对应位 | cf |
位测试并置1 bit test and set |
bts opd, ops | 在bt指令的基础上,将1→opd的对应位 | cf |
正向位扫描 bit scan forward |
bsf reg, ops | 从0位开始扫描ops各位,若均为0,则zf=1,否则将第一个为1的位置值 →reg,zf=0 |
zf |
反向位扫描 bit scan reverse |
bsr reg, ops | 从最高位开始扫描ops各位,若均为0,则zf=1,否则,将首先碰到的为1的位置值→reg,zf=0 | zf |
测试 test |
test opd, ops | (ops)∧(opd) | sf,zf,pf; 0→of,cf |
逻辑加 inclusive or |
or opd, ops | (opd)∨(ops)→opd | sf,zf,pf; 0→of,cf |
按位加 exclusive or |
xor opd, ops | 加法,就是用异或的计算方法了 | sf,zf,pf; 0→of,cf |
算术左移 shift arithmetic left |
sal opd, 1 ;sal opd, cl; sal opd, 8位立即数 |
cf中的值是最后移入位的值 | sf,zf,pf,cf |
逻辑左移 shift logic left |
shl opd, 1; shl opd, cl shl opd, 8位立即数 |
cf中的值是最后移入位的值 | sf,zf,pf,cf |
双精度左移 double precision shift left |
shld opd, reg,八位立即数 shld opd, reg, cl |
将reg的最高n位移入opd的低n位中,reg保持不变,opd最后移入的一位保存在cf中 | cf,sf,zf,pf |
算术右移 shift arithmetic rigtht |
sar opd,1; sar opd, cl sar opd, 8位立即数 |
将(opd)向右移动n个指定的次数且最高位保持不变,cf的内容为最后移入位的值 | sf,zf,pf,cf 等 |
逻辑右移 shift logical right |
shr opd, 1; shr opd cl shr opd, 8位立即数 |
将(opd)向右移动n规定的次数,最高位补入0,cf的内容为最后移入位的值 | sf,zf,pf,cf 等 |
双精度右移 double precision shift right |
shrd opd, reg,8位立即数 shrd opd, reg, cl |
将reg的最低n位移入opd高n位中,reg保持不变,opd最后移出的一位保存在cf中 | cf,sf,zf,pf |
循环右移 rotate rigth |
ror opd, 1; ror opd cl ror opd, 8位立即数 |
将目的操作数的最高位和最低位连接起来,组成一个环,将环中的所有位一起向右移动n位规定的数目(cl或立即数确定),cf为最后移入位的值 | cf |
循环左移 rotate left |
rol opd,1; rol opd cl rol opd, 8位立即数 |
同上,向左移动 | cf |
带进位的循环右移 rotate right through carry |
rcr opd, 1; rcr opd, cl rcr opd, 8位立即数 |
cf在最低位,与目的操作数连成环,移动 | cf |
带进位的循环左移 rotate left through carry |
rcl opd, 1; rcl opd, cl rcl opd, 8位立即数 |
cf在最高位,与目的操作数连成环,移动指定的位数 | cf |
六、寻址方式
寻址方式 |
格式 |
功能 |
实例 |
寄存器寻址 | R | 寄存器R的内容就是操作数(R是任意寄存器个别指令的限制除外) R可以是ax,bx,cx,dx,cs,ds,ss,es……. |
inc bx |
寄存器间接寻址 | [R] SS:[R]; 堆栈段 DS:[R]; 数据段 |
操作数在主存储器中,而操作数的偏移地址EA在指明的寄存器中 16位:只能是bx,bp,si,di 32位:通用寄存器(eax,ebx,ecx,edx,edi,esi,ebp,esp) 未指明段时,bp,ebp,esp为堆栈段,其余是数据段 |
mov a, [si] mov cx, [ebp] |
变址寻址 | 16位:[R+V],[R]+V,V[R] 32位:[R*F+V], [R*F]+V,V[R*F] |
操作数在主存储器中,偏移地址EA在指定寄存器R的内容乘以比例因子F与给出位移量V的和。 位移量V是不超过16位或不超过32位的二进制补码表示的有符号数(立即数),也可以是符合语法规则的数值表达式,变量,标号, 最后计算的偏移量是无符号数, 未明确段时,规则如上 |
mov al, [ebx*2]+5 add –2[bp], ax mov 2*10h[si] |
基址加变址寻址 | 16位:[bx/bp+si/di+V] V[bx/bp][si/di] V[bx/bp+si/di] 32位:[BR+IR*F+V], V[BR][IR*F], V[BR+IR*F] |
操作数在主存储器中,偏移地址EA是指令中基址寄存器的内容、变址寄存器的内容乘以比例因子、位移量V三项之和 32位时IR不能是esp, br中的来确定段 |
mov ax, 8[bx][si] mov eax, –6[edi*2][ebp] |
立即寻址 | n | 所提供额操作数是紧跟在指令码后面的一个采用8位、16位或32位二进制补码表示的有符号书,构成指令的一部分 n是立即数,可以是占用1个字节,2个字节,4个字节的存储单元,具体的类型必须要表示出来,根据指令的其它部分来决定,n只能是常数或结果为确定值的表达式,且只能做源操作数 |
mov word ptr [si],12h add eax, -12345678h |
直接寻址 | 段寄存器名:[n] 变量 变量+常量 |
操作数在主存储器中, n是一个数值或数值表达式时,直接表明操作数的偏移地址值,且为无符号数,[n]不能指明段寄存器,所以加了一个段说明符, 变量或变量+常量的地址表达式在汇编过程中被转换成“段寄存器名:[n]”的形式,期中n是汇编程序计算地址表达式得到的结果, |
mov ds:[20h], cl inc buf; (buf是定义的变量) mov ax, array1 mov array, bx sub cx, array3 mov dx, array4+3 (array* 是定义的变量) |