中大某君的总结。
发信人: jwjhk (无因为情), 信区: Modern_Elec
标 题: [转载] 8086汇编指令小结
发信站: 逸仙时空 Yat-sen Channel (Sat Mar 24 21:23:26 2007), 站内信件
【 以下文字转载自 EE 讨论区 】
【 原文由 iWater 所发表 】
>>目录<<
·8086/8088 寄存器组
一、通用寄存器
二、段寄存器
三、指令指针
四、标志寄存器
·8086/8088 寻址方式
0.固定寻址
一、立即数寻址
1.立即寻址
二、寄存器操作数寻址
2.寄存器寻址
三、存储器操作数寻址
3.直接寻址
4.寄存器间接寻址
5.寄存器相对寻址
6.基址变址寻址
7.相对基址变址寻址
四、I/O端口寻址
·8086/8088 指令系统
一、数据传送
二、算术运算
三、逻辑运算
四、串操作
五、控制传送
六、处理器控制
符号说明
━━━━┯━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
含义 │ 符号 │ 备 注
────┼────┼─────────────────────────
操作数 │OPRD │包括存储器、寄存器、立即数,可接8,16,32指明位数
存储器 │Mem │可接8,16,32表明操作数位数,如Mem32表示字操作数
累加器 │AReg │可接8, 16表明累加器的位数,AReg8即AL、AReg16即AX
寄存器 │Reg │可接8,16,32表明寄存器位数,如Reg16表示16位寄存器
段寄存器│Seg │代码段CS,数据段DS,堆栈段SS,附加段ES
标志位 │Flags │O D I T|S Z A P C
立即数 │Im │
有效地址│EA │Effective Address,即偏移量,其值不超过FFFFH
物理地址│PA │Physical Address
传送至 │<--, -->│
交换 │<---> │
可选 │{ } │
取内容 │( ) │(Reg)表示寄存器Reg的内容
取地址 │[ ] │[Mem]表示存储单元Mem的有效地址
━━━━┷━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
·8086/8088 寄存器组
8086/8088包括四个16位数据寄存器,两个16位指针寄存器,两个16位变址
寄存器,一个16位指令指针,四个16位段寄存器,一个16位标志寄存器。
这14个16位寄存器分成四组,它们的名称和分组情况如下:
┌─┬─┐
│AH│AL│AX \ ┐
│BH│BL│BX \ 数据 │
│CH│CL│CX / 寄存器 │
│DH│DL│DX / │
└─┴─┘ ├ 通用寄存器
┌───┐ │
│ BP │基址指针 \ 指针 │
│ SP │堆栈指针 / 寄存器 │
│ SI │源地址 \ 变址 │
│ DI │目的地址 / 寄存器 ┘
└───┘
┌───┐
│ IP │指令指针 \ 控制
│ FLAG │标志寄存器/ 寄存器
└───┘
┌───┐
│ CS │代码段 \
│ DS │数据段 \ 段
│ SS │堆栈段 / 寄存器
│ ES │附加段 /
└───┘
一、通用寄存器(General Register)
通用寄存器的专门用途
━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
寄存器 │ 用 途
─────┼─────────────────────────────
AX │字乘法,字除法,字I/O
AH │字节乘法,字节除法
AL │字节乘法,字节除法,字节I/O,十进制算术运算
BX │存储器指针
CX │串操作或循环控制中的计数器
CL │移位计数器
DX │字乘法,字除法,间接I/O
BP │存储器指针(存取堆栈的指针)
SP │堆栈指针
SI │存储器指针(串操作中的源指针)
DI │存储器指针(串操作中的目的指针)
━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1.数据寄存器
数据寄存器主要用于保存操作数或运算结果等信息,它们的存在节省了为存
取操作数所需占用总线和访问存储器的时间。
四个16位的数据寄存器可分解成八个独立的8位寄存器,这八个8位的寄存器
有各自的名称,均可独立存取。
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AX, AL│累加器(Accumulator) 通过它进行操作所花时间可能最少
BX │基(Base)地址寄存器 唯一可作为存储器指针的数据寄存器
CX │计数(Count)寄存器 用来控重复制循环次数或移位位数
DX │数据(Data)寄存器 存放被除数高16位或余数,还有I/O地址
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2.指针和变址寄存器
指针和变址寄存器主要用于存放某个存储单元地址的偏移,或某组存储单元
开始地址的偏移,即作为存储器(短)指针使用。作为通用寄存器,它们也可以
保存16位算术逻辑运算中的操作数和运算结果,有时运算结果就是所需要的存储
单元地址的偏移。
利用指针和变址寄存器不仅能够有效地缩短机器指令的长度,而且能够实现
多种存储器操作数的寻址,从而方便地实现对多种类型数据的操作。
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
BP和SP│BP基指针(Base Pointer),SP堆栈指针(Stack Pointer)
│BP主要用于给出堆栈中数据区基址的偏移,便于直接存取堆栈数据
│SP只保存堆栈栈顶地址的偏移
───┼───────────────────────────────
SI和DI│SI源变址(Source Index),DI目的变址(Destination Index)
│在字符串操作中,规定由SI给出源指针,DI给出目的指针
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
二、段寄存器(Segment Register)
8086/8088 CPU 依赖其内部的四个段寄存器实现寻址1M字节物理地址空间。
8086/8088把1M字节地址空间分成若干逻辑段,当前使用段的段值存放在段寄存器
中,由段值和段内偏移形成20位地址:物理地址=段值×16+偏移。
8086/8088 CPU 的四个段寄存器均是16位的,分别称为:
┌ 代码段(Code Segment) 寄存器CS
│ 数据段(Data Segment) 寄存器DS
│ 堆栈段(Stack Segment)寄存器SS
└ 附加段(Extra Segment)寄存器ES
三、指令指针(Instruction Pointer)
8086/8088 CPU 中的指令指针IP(Instruction Pointer)也是16位的,它类似
于8080/8085中的程序计数器PC(Program Counter)。指令指针IP给出接着要执行
指针在代码段中的偏移。
四、标志寄存器(Flag Register)
8086/8088 CPU 中有一个16位的标志寄存器,包含了9个标志,主要用于反映
处理器的状态和运算结果的某些特征。各标志在标志寄存器中的位置如下:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌─┬─┬─┬─┬─┬─┬─┬─┳─┬─┬─┬─┬─┬─┬─┬─┐
│ │ │ │ │OF│DF│IF│TF┃SF│ZF│ │AF│ │PF│ │CF│
└─┴─┴─┴─┴┬┴┬┴┬┴┬┻┬┴┬┴─┴┬┴─┴┬┴─┴┬┘
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ 进位标志
│ │ │ │ │ │ │ └─ 奇偶标志
│ │ │ │ │ │ └─ 辅助进位标志
│ │ │ │ │ └─ 零标志
│ │ │ │ └─ 符号标志
│ │ │ └─ 追踪标志
│ │ └─ 中断标志
│ └─ 方向标志
└─ 溢出标志
有些指令的执行会影响部分标志,而有些指令的执行不会影响标志;反之,
有些指令的执行受某些标志的影响,而有些指令的执行不受标志的影响。
1.运算结果标志
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
(1) 进位标志CF(Carry Flag)
主要用于反映运算是否产生进位或借位。如果运算结果的最高位产生一个
进位或借位,则CF=1,否则CF=0。
移位指令也把操作数的最高位或最低位移入CF。
───────────────────────────────────
(2) 零标志ZF(Zero Flag)
用于反映运算结果是否为0。如果运算结果为0,则ZF=1,否则ZF=0。
───────────────────────────────────
(3) 符号标志SF(Sign Flag)
用于反映运算结果的符号位。SF与运算结果的最高位相同。
───────────────────────────────────
(4) 溢出标志OF(Overflow Flag)
用于反映有符号数加减运算是否引起溢出。如果运算结果超出了8位或16位
有符号数的表示范围(字节运算时大于127或小于-128,字运算时大于32767或
小于-32768),则OF=1,否则OF=0。
───────────────────────────────────
(5) 奇偶标志PF(Parity Flag)
用于反映运算结果中“1”的个数。如果“1”的个数为偶数,则PF=1,否则
PF=0。
───────────────────────────────────
(6) 辅助进位标志AF(Auxiliary Carry Flag)
在字节操作时,如发生低半字节向高半字节进位或借位;在字操作时,如
发生低字节向高字节进位或借位,则AF=1,否则AF=0。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2.状态控制标志
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
(1) 方向标志DF(Direction Flag)
决定串操作指令执行时有关指针寄存器调整方向。
当DF=1时,串操作指令按减方式改变有关存储器指针值;
当DF=0时,串操作指针按加方式改变有关存储器指针值。
───────────────────────────────────
(2) 中断允许标志IF(Interrupt-enable Flag)
决定CPU是否响应外部可屏蔽中断请求。
当IF=1时,CPU能够响应外部的可屏蔽中断请求;
当IF=0时,CPU则不响应外部的可屏蔽中断请求。
───────────────────────────────────
(3) 追踪标志TF(Trap Flag)
当追踪标志TF被置1后,CPU进入单步方式,即在一条指令执行后,产生一个
单步中断。这主要用于程序的调试。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
·8086/8088 的寻址方式
“高高低低”原则、逻辑地址的表示“段值:偏移”、物理地址=段值×16+偏移
段寄存器的引用规定
━━━━━━━━━━━━┯━━━━━━━┯━━━━━━━┯━━━━━━
访问存储器涉及的方式 │ 约定段寄存器 │ 可选段寄存器 │ 偏移
────────────┼───────┼───────┼──────
取指令 │ CS │ 无 │ IP
堆栈操作 │ SS │ 无 │ SP
一般数据存取 │ DS │ CS, ES, SS │ 有效地址
源数据串 │ DS │ CS, ES, SS │ SI
目的数据串 │ ES │ 无 │ DI
BP作为指针寄存器 │ SS │ CS, DS, ES │ 有效地址
━━━━━━━━━━━━┷━━━━━━━┷━━━━━━━┷━━━━━━
注:可选段寄存器指可作为段超越前缀改变的段寄存器,有效地址指段内偏移
8086/8088 接受三种类型的操作数:
一、立即操作数: 数据作为指令的一部分,紧跟在操作码的后面
二、寄存器操作数:数据存在CPU的某个寄存器中
三、存储器操作数:数据存在存储器中,操作数用来指出数据在存储器中的位置
针对前两种操作数的寻址方式是立即寻址和寄存器寻址,其余5种方式都是
指针存储器操作数的。
0.固定寻址
固定寻址又称为隐含寻址,即指令中不指明操作数,但隐含在操作码中。如
字扩展指令CBW,仅有操作码,无操作数,但指令扩展AL中字节的符号,把它送至
AH中,这里的操作数AL是隐含在操作码中的。又如乘法指令MUL,是单操作数指令
形式(MUL OPRD),只指示了一个操作数OPRD,另一操作数未指明,也是隐含的,
为AL或AX,同样乘积的存放地址也是隐含的,为AX或DX,AX。
【特点】不需要计算有效地址,执行速度快,多为单字节指令
一、立即数寻址
1.立即寻址:操作数直接包含在指令中,紧跟在操作码之后存放在代码段,执行
时直接从指令队列中取出,不必执行总线周期访问存储器,操作数称为立即数
【特点】执行速度快,只能用于源操作数,主要用来对寄存器赋值
〖例〗MOV AX, 1234H
这条指令的机器码为:B8 34 12,占3字节,含义是将立即数1234H送到寄存
器AX中,存放按“高高低低”原则,即高位字节存入高地址,低位字节存入低地
址。示意图如下:
┌─┬─┐ ┌─┐
│AH│AL│ │ │
└┬┴┬┘ │B8│
│ └───┼34│
└─────┼12│
└─┘
二、寄存器操作数寻址
2.寄存器寻址:操作数包含在CPU内部的寄存器中,指令中直接给出该寄存器名
对于16位操作数,寄存器可以是:AX,BX,CX,DX,BP,SP,SI,DI等
对于 8位操作数,寄存器可以是:AH,AL,BH,BL,CH,CL,DH,DL等
【特点】指令编码短,无需从存储器取数,执行速度快
〖例〗
INC CX ; 目的操作数为寄存器寻址
MOV SI, AX ; 源操作数和目的操作数均是寄存器器寻址
MOV AL, 5AH ; 源操作数为立即寻址,目的操作为寄存器寻址
※ 8086/8088规定,除串操作指令外,在一条指令中只能有一个操作数为存储器
操作数,或为源操作数,或为目的操作数
三、存储器操作数寻址
3.直接寻址:操作数在存储器中的16位有效地址由指令中直接给出
如果指令中没有用段超越前缀指明操作数在哪个段,则默认在数据段。
〖例〗MOV AX, [1234H]
这条指令的机器码为:A1 34 12,占3字节,含义是将DS段中偏移地址为
1234H的字单元中的内容送到AX中。
【注意】
(1)在直接寻址中,若指令中有效地址是一个16位数,
为不与立即寻址相混淆,应用方括号[]括起来,如上例;
若有效地址是一个符号地址,如MOV AX, DATA,则不用加方括号。
(2)若操作数不在数据段,则可用段超越前缀在有效地址前指明,如:
MOV ES:[2500H], BL
该指令表示目的操作数不在数据段,而在附加段,PA=(ES*16)+2500H
4.寄存器间接寻址:操作数的有效地址在BX、BP、SI、DI这4个寄存器之一中
不使用段超载前缀时:
(1)当指定BX、SI或DI为间址寄存器,则操作数在数据段中,DS的内容为段基址
┌ (BX)
EA = ┤ (SI) PA = (DS×16)+EA
└ (DI)
(2)当指定BP为间址寄存器,则操作数在堆栈段中,SS寄存器中的内容为段基址
EA = (BP) PA = (SS×16)+EA
〖例〗
MOV AX, [DI] ;源操作数为寄存器间接寻址,引用的段寄存器是DS
MOV [BP], CX ;目的操作数为寄存器间接寻址,引用的段寄存器是SS
MOV DL, CS:[BX] ;源操作数为寄存器间接寻址,引用的段寄存器指定为CS
【特点】可以用于表格处理,处理完表中的一项后,只要修改指针寄存器的内容
就可方便地处理表中的另一项
5.寄存器相对寻址:操作的有效地址是一个基址寄存器或变址寄存器的内容加上
指令中给定的8位/16位的位移量
┌ (BX)
├ (BP) ┌ 8位
EA = ┤ + ┤ 位移量
├ (SI) └ 16位
└ (DI)
寄存器相对寻址和寄存器间接寻址很相似,只是多了一个位移量。
〖例〗MOV AL, 53H[BX] ;或写成 MOV AL, [BX+53H]
设 (DS)=3000H, (BX)=8000H, (38053H)=7FH,则源操作数的PA为:
PA = (3000H)*16 + 8000H + 53H = 38053H
指令执行后,将存储器38053H单元的内容7FH送入AL。
【特点】可以用于表格处理,表格的首地址可设置为指令中的位移量,利用修改
基址或变址寄存器的内容来存取表格中的项值
6.基址变址寻址:操作数有效地址是一个基址寄存器和一个变址寄存器内容之和
┌ (BX) ┌ (SI)
EA = ┤ + ┤
└ (BP) └ (DI)
〖例〗MOV AX, [BX][DI] ;或写成 MOV AX, [BX+DI]
设 (DS)=2000H, (BX)=0256H, (DI)=6694H, (268EAH)=68H, (268EBH)=01H,则
EA = 0256H + 6694H = 68EAH
PA = (DS)*16 + EA = 2000H*16 + 68EAH = 268EAH
指令执行后,把268EAH和268EBH两相邻单元的内容送到AX中,(AH)=01H,(AL)=68H
【特点】适用于数组或表格处理,用基址寄存器存放数组首地址,用变址寄存器
来定位数组中的各元素,或反之,由于两个寄存器都可改变,所以操作更灵活
7.相对基址变址寻址:操作数有效地址是一个基址寄存器和一个变址寄存器内容
再加上一个8位/16位的位移量之和
┌ (BX) ┌ (SI) ┌ 8位
EA = ┤ + ┤ + ┤ 位移量
└ (BP) └ (DI) └ 16位
〖例〗以下三条指令等价,源操作数为相对基址变址寻址,引用的段寄存器是DS
MOV AX, MASK[BX][SI]
MOV AX, MASK[BX+SI]
MOV AX, [MASK+BX+SI]
四、I/O端口寻址
在以Intel的80x86家族处理器为CPU的系统中,I/O端口地址和存储单元的地址
是各自独立的,分占两个不同的地址空间。8086/8088提供的I/O端口地址空间达
64K,因而可接64K个8位端口。I/O地址空间也可以定义16位和32位的端口。
I/O端口可以用立即操作数或DX寄存器寻址:
━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━
直接端口寻址│端口地址为8位立即数,值范围0~255
──────┼────────────────────────────
间接端口寻址│端口地址为DX寄存器内容,值范围0~65535
━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━
〖例〗
IN AL, 7 ;源操作数为直接端口寻址
IN AX, DX ;源操作数为间接端口寻址
OUT 40H, AX ;目的操作数为直接端口寻址
OUT DX, AL ;目的操作数为间接端口寻址
·8086/8088 指令系统
8086/8088 的指令系统可分为如下六个功能组:
一、数据传送(Data Transfer)
二、算术运算(Arithmetic)
三、逻辑运算(Logic)
四、串操作 (String Manipulation)
五、控制传送(Control Transfer)
六、处理器控制(Processor Control)
【规则】
(1)只有通用传送指令中的MOV, PUSH, POP是允许以段寄存器为操作数的指令
(2)源和目的不能同时是段寄存器
(3)代码段寄存器CS不能作为目的,指令指针IP既不能作为源,也不能作为目的
(4)立即数永远不能作为目的操作数
(5)源操作数和目的操作类型要一致,即同时为字节或字,但LDS, LES例外
(6)除了串操作指令外,源操作数和目的操作数不能同时是存储器操作数
一、数据传送指令(Data Transfer)
1.通用传送(General Purpose Transfer)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
MOV OPRD1, OPRD2 │数值传送,OPRD1 <-- OPRD2,操作数可为段寄存器
─────────┼─────────────────────────
PUSH OPRD16 │进栈指令,把16位数据压入堆栈顶,OPRD16可为段寄存器
POP OPRD16 │出栈指令,从堆栈顶弹出16位数据,OPRD16不可为CS
─────────┼─────────────────────────
XCHG OPRD1, OPRD2 │交换指令,把一个字节或一个字的源与目的操作互换
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
2.累加器专用传送(Accumulator Special Purpose Transfer)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
IN AReg, OPRD │输入指令,累加器 <-- 输入端口,OPRD为0~255或DX
OUT OPRD, AReg │输出指令,输出端口 <-- 累加器,OPRD为0~255或DX
─────────┼─────────────────────────
XLAT SRC_TABLE │查表转换,表的基地址在寄存器BX,以AL为表的下标,
│在表SRC_TABLE中查找相应数据,并把结果存放到AL中
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
3.地址-目的传送(Address Object Transfer)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
LEA Reg16, Mem │传送有效地址指令,Reg16 <-- [Mem]
─────────┼─────────────────────────
LDS Reg16, Mem32 │传送32位地址指针到数据段寄存器DS和通用寄存器Reg16
│Mem32段值部分-->DS,Mem32偏移部分-->Reg16
LES Reg16, Mem32 │传送32位地址指针到附加段寄存器ES和通用寄存器Reg16
│Mem32段值部分-->ES,Mem32偏移部分-->Reg16
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
4.标志寄存器传送(Flag Register Transfer)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
LAHF │把标志寄存器低8位(包括SZAPC标志)传送到寄存器AH的
│指定位(7,6,4,2,0),其他位(5,3,1)的内容无定义
SAHF │把寄存器AH指定位(7,6,4,2,0)传送至标志寄存器低8位
│的标志位SZAPC,但不影响高8位的ODIT标志
─────────┼─────────────────────────
PUSHF │把标志寄存器的内容压入堆栈顶
POPF │把堆栈顶的一个字传送到标志寄存器
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
二、算术运算指令(Arithmetic)
1.加法(Addition)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
ADD OPRD1, OPRD2 │普通加法,OPRD1 <-- OPRD1 + OPRD2
ADC OPRD1, OPRD2 │带进位加,OPRD1 <-- OPRD1 + OPRD2 + CF
─────────┼─────────────────────────
AAA │对AL中的由两个未组合BCD码相加后的结果进行校正
DAA │对AL中的由两个组合BCD码相加后的结果进行校正
─────────┼─────────────────────────
INC OPRD │加1指令,OPRD <-- OPRD + 1
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
2.减法(Subtraction)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
SUB OPRD1, OPRD2 │普通减法,OPRD1 <-- OPRD1 - OPRD2
SBB OPRD1, OPRD2 │带借位减,OPRD1 <-- OPRD1 - OPRD2 - CF
─────────┼─────────────────────────
AAS │对AL中的由两个未组合BCD码相减后的结果进行校正
DAS │对AL中的由两个组合BCD码相减后的结果进行校正
─────────┼─────────────────────────
DES OPRD │减1指令,OPRD <-- OPRD - 1
─────────┼─────────────────────────
NEG OPRD │取补指令,OPRD <-- 0 - OPRD
─────────┼─────────────────────────
CMP OPRD1, OPRD2 │比较指令,完成OPRD1 - OPRD2,结果反映在标志位上,
│但并不送回OPRD1
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
3.乘法(Multiplication)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
MUL OPRD │无符号数乘法,字节操作 AX <-- AL * OPRD8
│ 或 字操作 DX,AX <-- AX * OPRD16
IMUL OPRD │有符号数乘法,字操作 AX <-- AL * OPRD8
│ 或 字操作 DX,AX <-- AX * OPRD16
─────────┼─────────────────────────
AAM │对AX中的由两个未组合BCD码相乘后的结果进行校正
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
4.除法(Division)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
DIV OPRD │无符号数除法,字节操作 AX/OPRD8 商->AL,余->AH
│ 或 字操作 DX,AX/OPRD16 商->AX,余->DX
IDIV OPRD │有符号数除法,字节操作 AX/OPRD8 商->AL,余->AH
│ 或 字操作 DX,AX/OPRD16 商->AX,余->DX
─────────┼─────────────────────────
AAD │对AX中的两位未组合BCD码在两数相除以前进行校正
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
5.符号扩展(Sign Extension)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
CBW │字节转换为字,把AL中字节的符号扩展到AH
CWD │字转换为双字,把AX中节的符号扩展到DX
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
三、逻辑运算指令(Logic)
1.逻辑运算(Logic)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
NOT OPRD │非操作,把操作数OPRD取反,然后送回OPRD
AND OPRD1, OPRD2 │与操作, OPRD1 <-- OPRD1 · OPRD2 (按位进行)
OR OPRD1, OPRD2 │或操作, OPRD1 <-- OPRD1 + OPRD2 (按位进行)
XOR OPRD1, OPRD2 │异或操作,OPRD1 <-- OPRD1 ⊕ OPRD2 (按位进行)
─────────┼─────────────────────────
TEST OPRD1, OPRD2 │测试指令,把两操作数按位与,结果反映在标志位上,
│但并不送回OPRD1
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
2.移位(Shift)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
SHL │逻辑左移,左移、最高位-->CF、右补0
SHR │逻辑右移,右移、最低位-->CF、左补0
─────────┼─────────────────────────
SAL │算术左移,左移、最高位-->CF、右补0
SAR │算术右移,右移、最低位-->CF、符号位不变、左补符号
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
指令图示:
CF MSB 操作数 LSB
┌─┐ ┌────────────┐
│ ├←──┤ ←────────── ├←┐
└─┘ └────────────┘ │0
SHL, SAL
CF MSB 操作数 LSB
┌─┐ ┌────────────┐
┌→┤ │ ┌→┤ ──────────→ ├─┐
│ └─┘ 0│ └────────────┘ │
└──────────────────────┘
SHR
CF MSB 操作数 LSB
┌─┐ ┌────────────┐
┌→┤ │ ┌→┤ ──────────→ ├─┐
│ └─┘ │ └┬───────────┘ │
│ └──┘ │
└──────────────────────┘
SAR
3.循环(Rotation)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
ROL │循环左移,左移、高位-->低位
ROR │循环右移,右移、低位-->高位
─────────┼─────────────────────────
RCL │带进位循环左移,左移、高位-->CF-->低位
RCR │带进位循环右移,右移、低位-->CF-->高位
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
指令图示:
CF MSB 操作数 LSB
┌─┐ ┌────────────┐
│ ├←┬←┤ ←────────── ├←┐
└─┘ │ └────────────┘ │
└────────────────┘
ROL
CF MSB 操作数 LSB
┌─┐ ┌────────────┐
│ ├←┬→┤ ──────────→ ├─┐
└─┘ ↑ └────────────┘ │
└────────────────┘
ROR
CF MSB 操作数 LSB
┌─┐ ┌────────────┐
┌─┤ ├←──┤ ←────────── ├←┐
│ └─┘ └────────────┘ │
└──────────────────────┘
RCL
CF MSB 操作数 LSB
┌─┐ ┌────────────┐
┌→┤ ├──→┤ ──────────→ ├─┐
│ └─┘ └────────────┘ │
└──────────────────────┘
RCR
四、串操作指令(String Manipulation)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
MOVS │字符串传送,[DI] <-- [SI],然后SI、DI分别增1或减1
─────────┼─────────────────────────
SCAS │字符串扫描,比较AL与[DI],然后DI增1或减1
─────────┼─────────────────────────
CMPS │字符串比较,比较[SI]与[DI],然后SI、DI分别增1或减1
─────────┼─────────────────────────
LODS │字符串装入,把字符串中的一个字符装入到累加器中
STOS │字符串存储,把累加器的值存到字符串中(替换)
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
重复前缀
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
REP │判断CX、CX减1、重复串操作,直至CX=0
─────────┼─────────────────────────
REPZ / REPE │判断CX、CX减1、重复串操作,直至CX=0或ZF=0
─────────┼─────────────────────────
REPNZ / REPNE │判断CX、CX减1、重复串操作,直至CX=0或ZF=1
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
五、控制传送指令(Control Transfer)
1.调用、返回、无条件转移
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
CALL OPRD │子程序(过程)调用指令
RET {Im} │返回指令
─────────┼─────────────────────────
JMP OPRD │无条件转移指令
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
2.条件转移
条件转移指令表
━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━
指令 │ 转移条件 │ 转移说明 │ 其他说明
──────┼────────┼────────────┼──────
JZ / JE │零标志 ZF=1 │等于0或相等转移 │ 单个标志
JNZ / JNE │零标志 ZF=0 │不等于0或不相等转移 │
──────┼────────┼────────────┼──────
JS │符号标志 SF=1 │为负转移 │ 单个标志
JNS │符号标志 SF=0 │为正转移 │
──────┼────────┼────────────┼──────
JC │进位标志 CF=1 │进位或借位转移 │ 单个标志
JNC │进位标志 CF=0 │无进位或借位转移 │
──────┼────────┼────────────┼──────
JO │溢出标志 OF=1 │溢出转移 │ 单个标志
JNO │溢出标志 OF=0 │不溢出转移 │
──────┼────────┼────────────┼──────
JP / JPE │奇偶标志 PF=1 │偶转移 │ 单个标志
JNP / JPO │奇偶标志 PF=0 │奇转移 │
──────┼────────┼────────────┼──────
JA / JNBE │CF + ZF = 0 │> 高于转移 │ 无符号数
JAE / JNB │CF = 0 │>= 高于等于转移 │
JB / JNAE │CF = 1 │< 低于转移 │
JBE / JNA │CF + ZF = 1 │<= 低于等于转移 │
──────┼────────┼────────────┼──────
JG / JNLE │SF⊕OF + ZF = 0 │> 大于转移 │ 有符号数
JGE / JNL │SF⊕OF = 0 │>= 大于等于转移 │
JL / JNGE │SF⊕OF = 1 │< 小于转移 │
JLE / JNG │SF⊕OF + ZF = 1 │<= 小于等于转移 │
━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━
注:
(1)条件转移指令不影响标志。
(2)所有条件转移都只是段内转移。
(3)条件转移采用相对转移方式,即通过在IP上加上一个地址差的方法实现转移,
范围在-127~+128之间,如果目标超出此范围,则必须借助于无条件转移指令。
(4)溢出标志 OF = Cn⊕Cn-1 其中Cn和Cn-1为最高位和次高位的进位。
3.重复控制
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
LOOP │计数循环指令,若CX减1后不等于0则转移
─────────┼─────────────────────────
LOOPZ / LOOPE │等于/全零循环指令,若CX减1后不等于0且ZF=1则转移
LOOPNZ / LOOPNE │不等于/非零循环指令,若CX减1后不等于0且ZF=0则转移
─────────┼─────────────────────────
JCXZ │跳转指令,若CX等于0则转移
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
4.中断
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
INT Im │启动在中断类型号Im所规定的中断过程(Im=0~255)
─────────┼─────────────────────────
INTO │若溢出标志 O=1 则启动中断类型号为4的中断
─────────┼─────────────────────────
IRET │退出中断过程,返回到中断时的断点处
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
六、处理器控制指令(Processor Control)
1.标志操作(Flag Operation)
━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
CLC │标志C清零 CF=0
STC │标志C置位 CF=1
CMC │标志C取反
─────────┼─────────────────────────
CLD │标志D清零 DF=0
STD │标志D置位 DF=1
─────────┼─────────────────────────
CLI │标志I清零 IF=0
STI │标志I置位 IF=1
━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
2.处理器暂停(Processor Halt)
HLT 使8086进入暂停状态
3.处理器脱离(Processor Escape)
ESC 把控制权交给协处理器
4.处理器等待(Processor Wait)
WAIT 在8086的TEST引线无效条件下,使CPU进入等待状态
5.总线锁定(Bus Lock)
LOCK 前缀,可使8086的一条输出引线LOCK有效,则在下一条
指令执行期间,把总线锁存,别的主设备不能控制总线
指令与标志参考表
━━━━━━━┯━━┯━━┯━━┯━━┯━━┯━━┯━━┯━━┯━━━
指令 │ OF │ SF │ ZF │ AF │ PF │ CF │ TF │ IF │ DF
───────┼──┴──┴──┴──┴──┴──┴──┴──┴───
数据传送 │除SAHF, POPF以外,均不影响标志位
──┬────┼──┬──┬──┬──┬──┬──┬──┬──┬───
│ADD, ADC│ √ │ √ │ √ │ √ │ √ │ √ │ │ │
│SUB, SBB│ √ │ √ │ √ │ √ │ √ │ √ │ │ │
│INC, DEC│ √ │ √ │ √ │ √ │ √ │ - │ │ │
│MUL,IMUL│ √ │ - │ - │ - │ - │ √ │ │ │
算 │DIV,IDIV│ - │ - │ - │ - │ - │ - │ │ │
术 │AAA, AAS│ - │ - │ - │ √ │ - │ √ │ │ │
运 │DAA, DAS│ - │ √ │ √ │ √ │ √ │ √ │ │ │
算 │AAM, AAD│ - │ √ │ √ │ - │ √ │ - │ │ │
│NEG │ √ │ √ │ √ │ √ │ √ │ √ │ │ │
│CMP │ √ │ √ │ √ │ √ │ √ │ √ │ │ │
├────┼──┴──┴──┴──┴──┴──┴──┴──┴───
│CBW, CWD│不影响标志位
──┼────┼───────────────────────────
│ 逻辑 │NOT不影响标志位
│ 运算 │AND,OR,XOR,TEST影响O,S,Z,P,C,未定义A
逻 ├─┬──┼──┬──┬──┬──┬──┬──┬──┬──┬───
辑 │移│一位│ √ │ √ │ √ │ - │ √ │ √ │ │ │
运 │位│多位│ - │ √ │ √ │ - │ √ │ √ │ │ │
算 ├─┼──┼──┼──┼──┼──┼──┼──┼──┼──┼───
│循│一位│ √ │ │ │ │ │ √ │ │ │
│环│多位│ - │ │ │ │ │ √ │ │ │
──┴─┴──┼──┴──┴──┴──┴──┴──┴──┴──┴───
串操作 │MOVS, LODS, STOS均不影响标志位,只测试D
│SCAS, CMPS也测试D,但影响标志位O, S, Z, A, P, C
──┬────┼───────────────────────────
│ │CALL, RET, JMP均不影响标志位
├────┼───────────────────────────
控 │条件转移│只测试标志位,不影响标志位
制 ├────┼───────────────────────────
传 │重复控制│均不影响标志位
送 ├────┼───────────────────────────
│ 中 │INT, INTO仅使标志位T和I清零,不影响其他标志位
│ 断 │IRET把标志位恢复中断以前的状态,影响所有标志位
──┼────┼───────────────────────────
处控│标志操作│仅影响相对应的标志位
理制├────┼───────────────────────────
器 │ │HLT, ESC, WAIT, LOCK均不影响标志位
━━┷━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━
注:√ 指令影响标志 - 指令对标志的影响未定义 空 指令不影响标志
(1)乘法指令MUL, IMUL执行后,若结果的高半部分有效,则C=1,O=1,否则C=0,O=0
(2)取补指令NEG执行后,一般总是使标志C=1,除非操作数为零才使C=0
(3)逻辑运算指令AND, OR, XOR, TEST执行后使C=0, O=0
(4)移位和循环指令如果只移一位,执行前后符号位发生变化则O=1,否则O=0
-- iWater, 2003-11