汇编语言 8086指令系统整理。
数据传送类指令
通用数据传送指令
传送指令 mov
| 1 | mov reg/mem, imm ; 立即数送寄存器或主存 | 
交换指令 xchg
| 1 | xchg reg, reg/mem ; 将寄存器与寄存器或主存的内容交换 | 
换码指令 xlat
| 1 | xlat ; al <- ds:[bx+al] | 
堆栈操作指令
堆栈是一个”先进后出”的主存区域,位于堆栈段中。
存储方式是:高位栈底,低位栈顶。
进栈指令 push
| 1 | push r16/m16/seg ; sp <- sp-2, ss:[sp] <- r16/m16/seg | 
出栈指令 pop
| 1 | pop r16/m16/seg ; r16/m16/reg, sp <- sp + 2 | 
标志传送指令
标志送AH指令 lahf
| 1 | lahf ; ah <- flags的低字节 | 
AH送标志指令 sahf
| 1 | sahf ; flags的低字节 <- ah | 
标志进栈指令 pushf
| 1 | pushf ; sp <- sp-2, ss:[sp] <- flags | 
标志出栈指令 popf
| 1 | popf ; flags <- ss:[sp], sp <- sp+2 | 
标志位操作
| 1 | clc ; CF <- 0 | 
地址传送指令
有效地址传送指令 lea
| 1 | lea r16, mem ; r16 <- mem的有效地址EA | 
指针传送指令 lds les
| 1 | lds r16, mem ; r16 <- mem, ds <- mem+2 | 
算术运算类指令
首先了解几个状态标志,它们在算术运算中起着重要作用。
进位标志 CF(Carry Flag):
针对无符号整数运算设计。
当加减运算的结果的最高有效位有进位或借位时,设置CF = 1溢出标志 OF(Overflow Flag):
针对有符号整数运算设计。
当有符号数进行加减运算的结果超出范围时,设置OF = 1零标志 ZF(Zero Flag):
反映运算结果是否为 0,当运算结果为 0 时,设置ZF = 1符号指令 SF(Sign Flag):
反映运算结果是正数还是负数,当运算结果最高位为 1 时,SF = 1奇偶校验 PF(Parity Flag):
反映运算结果最低字节中 1 的个数时偶数还是奇数,为偶数时,PF = 1调整标志 AF(Adjust Flag):
当加减运算时最低半字节有进位或借位时,AF = 1
加法指令 add
| 1 | add reg, imm/reg/mem ; reg <- res+imm/reg/mem | 
带进位加法指令 adc
| 1 | adc reg, imm/reg/mem ; reg <- res+imm/reg/mem+cf | 
增量指令 inc
| 1 | inc reg/mem ; reg/mem <- reg/mem+1 | 
减法指令 sub
| 1 | sub reg, imm/reg/mem ; reg <- res-imm/reg/mem | 
 带借位减法指令 sbb
| 1 | sbb reg, imm/reg/mem ; reg <- res-imm/reg/mem-cf | 
减量指令 dec
| 1 | dec reg/mem ; reg/mem <- reg/mem-1 | 
求补指令 neg
| 1 | neg reg/mem ; reg/mem <- 0-reg/mem | 
比较指令 cmp
| 1 | cmp reg, imm/reg/mem ; reg-imm/reg/mem | 
无符号数乘法指令 mul,有符号数乘法指令 imul
| 1 | mul r8/m8 ; 无符号字节乘: ax <- al·r8/m8 | 
无符号二进制数除法指令 div,有符号二进制数除法指令 idiv
| 1 | div r8/m8 ; 无符号数字节除: al <- ax除以r8/m8的商 | 
符号扩展指令 cbw cwd
| 1 | cbw ; al符号扩展到ax | 
位操作类指令
逻辑与指令 and
| 1 | and dest, src ; dest <- dest&src | 
逻辑或指令 or
| 1 | or dest, src ; dest <- dest|src | 
逻辑异或指令 xor
| 1 | xor dest, src ; dest <- dest^src | 
逻辑非指令 not
| 1 | not reg/mem ; reg/mem <- ~reg/mem | 
测试指令 test
| 1 | test dest, src ; dest&src | 
移位指令 shl shr sal sar
| 1 | shl reg/mem, 1/cl ; 逻辑左移: reg/mem左移1/cl位,最低位补0,最高位进入CF | 
循环移位指令 rol ror rcl rcr
| 1 | rol reg/mem, 1/cl ; 不带进位循环左移 | 
控制转移类指令
段内转移是指在当前代码段 64KB 范围内转移,因此不需要改变 CS 段地址,只需更改 IP 偏移地址。
如果转移范围可以用一个 8 位数(-128~127)表达,则形成短转移(short jump)
如果转移范围可以用一个 16 位数表达,则形成近转移(near jump)段间转移是指从当前代码段跳转到另一个代码段,此时需要更改 CS 段地址和 IP 偏移地址。
这种转移也称为远转移(far jump),转移的目标地址用一个 32 位数表达,叫做 32 位远指针,即逻辑地址。
无条件转移指令 jmp,分为四种格式。
| 1 | jmp label ; ip <- ip+位移量 | 
| 1 | jmp r16/m16 ; ip <- r16/m16 | 
| 1 | jmp far ptr label ; ip <- label的偏移地址, cs <- label的段地址 | 
| 1 | jmp far ptr mem ; ip <- [mem], cs <- [mem + 2] | 
条件转移指令,具体指令如下表给出。
| 1 | jcc label ; 条件满足,发生转移: ip <- ip+8位位移量 | 
- 根据单个条件标志的设置情况转移
| 指令 | 英文 | 含义 | 格式 | 测试条件 | 
|---|---|---|---|---|
| JZ/JE | jump if zero/equal | 结果为零/相等则转移 | JZ/JE OPR | ZF=1 | 
| JNZ/JNE | jump if not zero/equal | 结果不为零/不相等则转移 | JNZ/JNE OPR | ZF=0 | 
| JS | jump if sign | 结果为负则转移 | JS OPR | SF=1 | 
| JNS | jump if not sign | 结果为正则转移 | JNS OPR | SF=0 | 
| JO | jump if overflow | 溢出则转移 | JO OPR | OF=1 | 
| JNO | jump if not overflow | 不溢出则转移 | JNO OPR | OF=0 | 
| JP/JPE | jump if parity/parity even | 奇偶位为1则转移 | JP/JPE OPR | PF=1 | 
| JNP/JNPE | jump if not parity/parity even | 奇偶位为0则转移 | JNP/JNPE OPR | PF=0 | 
| JB/JNAE/JC | jump if below/not above、not equal/carry | 低于/不高于或不等于/进位为1则转移 | JB/JNAE/JC OPR | CF=1 | 
| JNB/JAE/JNC | jump if not below/ above、equal/not carry | 不低于/高于或等于/进位为零则转移 | JNB/JAE/JNC OPR | CF=0 | 
- 比较两个无符号数,并根据比较的结果转移
| 指令 | 英文 | 含义 | 格式 | 测试条件 | 等价于 | 
|---|---|---|---|---|---|
| JB/JNAE/JC | jump if below/not above、not equal/carry | 低于/不高于或不等于/进位为1则转移 | JB/JNAE/JC OPR | CF=1 | < | 
| JNB/JAE/JNC | jump if not below/ above、equal/not carry | 不低于/高于或等于/进位为零则转移 | JNB/JAE/JNC OPR | CF=0 | ≥ | 
| JBE/JNA | jump if below/equal、not above | 低于/等于、不高于则转移 | JBE/JNA OPR | CF并ZF=1 | ≤ | 
| JNBE/JA | jump if not below/not equal、above | 不低于/不等于、高于则转移 | JNBE/JA OPR | CF并ZF=0 | > | 
3. 比较两个带符号数,并根据比较的结果转移
| 指令 | 英文 | 含义 | 格式 | 测试条件 | 等价于 | 
|---|---|---|---|---|---|
| JL/JNGE | jump if less、not greater/equal | 小于、不大于/不等于则转移 | JL/JNGE OPR | SF异或CF=1 | < | 
| JNL/JGE | jump if not less、greater/equal | 不小于、大于/等于则转移 | JNL/JGE OPR | SF异或CF=0 | ≥ | 
| JLE/JNG | jump if less/equal、not greater | 小于/等于、不大于则转移 | JLE/JNG OPR | (SF异或CF)并ZF=1 | ≤ | 
| JNLE/JG | jump if not less/not equal、 greater | 不小于/不等于、大于则转移 | JNLE/JG OPR | (SF异或CF)并ZF=0 | > | 
循环指令。(实际上循环流程可以由前面的转移指令实现)
| 1 | jcxz label ; cx = 0 则转移,否则顺序执行 | 
子程序调用指令 call,分为四种格式。
| 1 | call label ; 段内调用,相对寻址: sp <- sp-2, ss:[sp] <- ip | 
| 1 | call r16/m16 ; 段内调用,间接寻址: sp <- sp-2, ss:[sp] <- ip, ip <- r16/m16 | 
| 1 | call far ptr label ; 段间调用,直接寻址: sp <- sp-2, ss:[sp] <- cs | 
| 1 | call far ptr mem ; 段间调用,间接寻址: sp <- sp-2, ss:[sp] <- cs | 
子程序返回指令 ret,分为四种格式。
| 1 | ret ; 无参数段内返回: ip <- ss:[sp], sp <- sp+2 | 
| 1 | ret i16 ; 有参数段内返回: ip <- ss:[sp], sp <- sp+2, sp <- sp+i16 | 
| 1 | ret ; 无参数段间返回: ip <- ss:[sp], sp <- sp+2 | 
| 1 | ret i16 ; 有参数段间返回: ip <- ss:[sp], sp <- sp+2 | 
中断指令
| 1 | int i8 ; 中断调用指令,产生 i8 号中断 |