第三章 IMB PC机的指令系统和寻址方式

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第三章80X86的指令系统和寻址方式
概述
指令组成:由操作码字段和操作数字段组成
操作码:指明指令要执行的操作
操作数:指令执行过程中需要的数据
指令一般格式:
操作码操作数……操作数
·单地址指令:指令中只有一个操作数字段
如:加1指令:
INC OPR ;操作:(OPR)←(OPR)+1 减1指令:
DEC OPR ;操作:(OPR)←(OPR)–1
·二地址指令:指令中有二个操作数字段
如:加法指令:
ADD DST,SRC
;操作:(DST)←(DST)+(SRC)
传送指令:MOV DST,SRC
;操作:(DST)←(SRC)
指令执行以后,把运算结果存放到目的操作数DST中,源操作数SRC不改变。

·三地址指令:指令中有三个操作数字段,二个地址指明参加运算的操作数,一个地址指明结果存放地。

如:80286及其后继机型三地址乘法指令:IMUL REG,SRC,IMM
执行的操作:(REG)←(SRC)* IMM
80x86的大多数运算型指令采用二地址指令,少数采用三地址指令。

汇编语言是一种符号语言,在汇编语言程序中,指令操作码用指令助记符代替,操作数用符号或符号地址来表示,用助记符书写的指令与机器指令是一一对应。

3.1 80X86寻址方式
3.1.1 与数据有关的寻址方式
寻址方式:说明操作数所在地址的方法
80X86中,操作数有三类:
立即数
寄存器数
存储器操作数。

指令使用不同的寻址方式指明操作数所在地。

下面主要讨论8086/8088 寻址方式,与80X86实模式寻址方式相容。

以MOV指令为例进行说明。

MOV DST,SRC
操作:(DST)←(SRC)
DST:目的操作数
SRC:源操作数
讨论SRC 寻址方式
1、立即寻址方式——操作数直接存放在指令
中,紧跟在操作码之后,作为指令的一部分存放在代码段里。

例3.1 MOV AL,5
指令执行后,(AL)= 05H
操作码
立即数(8位)
MOV AL,5操作示意图
例3.2 MOV AX ,3064H
指令执行后,(AX )= 3064H
一般用法:
给寄存器或存储单元赋初值或者进行常量运算。

在汇编语言中,用EQU 伪指令定义的符号可以代替常数,例如:
COUNT EQU 5
MOV AL ,COUNT
这二个语句经汇编后与语句
MOV AL ,5等效。

2、 寄存器寻址方式——
操作数在指令指定的寄存器中。

16位操作数寄存器:AX 、BX 、CX 、DX 、SI 、
DI 、SP 、BP 、CS 、DS 、ES 、SS 等
立即数(16位)
图3.2 MOV AX ,3064H 操作示意图
8位操作数寄存器:AH、AL、BH、BL、CH、CL、DH和DL等。

例3.3MOV AX,BX;操作(AX)←(BX)
将BX中的值传送到AX中,BX值不变。

若指令执行前:(AX)= 3064H,(BX)= 1234H 则指令执行后:(AX)= (BX)= 1234H
优点:指令执行速度快。

下面几种寻址方式用于存储器操作数,确定存放操作数的存储单元的段地址和偏移地址。

偏移地址:可由各种成份组成,称有效地址EA。

组成EA的四种成分:
(1)位移量:存放在指令中的一个8位、16位或32位的数,它不是立即数,而是一个地址。

(2)基址:存放在基址寄存器中的内容,是有效地址中的基址部分,一般用来指向数据段中
数组或字符串的首址。

(3)变址:存放在变址寄存器中的内容,它通常用来访问数组中某个元素或字符串中某个字
符,起组内索引作用。

(4)比例因子:其值为1,2,4,8。

用于80386
及其后继机型。

EA = 基址+ (变址×比例因子)+ 位移量表3.1指出16/32 位EA的四种成分
四种成分16位寻址32位寻址
位移量0,8,16位0,8,32位
基址寄存器BX,BP 任何32位寄存器变址寄存器SI、DI 除ESP 以外的32
位通用寄存器
比例因子无1,2,4,8
对16位寻址,默认如下:
段地址——约定:寻址方式中用BP作基地址,用SS段寄存器;其他用DS段寄存器;串
指令中,目的数在附加段,用ES寄存器。

跨段——操作数不在基本约定段区内,使用跨段
前缀说明。

3、直接寻址方式——有效地址EA在指令代
码段中,存放在操作码之后的操作数字段。

默认操作数在数据段,用DS段寄存器。

物理地址=(DS)×16 + EA
例3.5 MOV AX,[2000H]
图3.3 例3.5执行情况
若(DS)= 3000H,
从指令可知,EA = 2000H
物理地址= 30000H + 2000H
= 32000H
指令操作:(AL)←(32000H)
(AH)←(32001H)
执行后:(AX)= 3050H
在汇编语言中,一般用符号地址代替数值地址,符号地址必须先用伪指令在数据段定义,然后再使用。

例:VALUE DW 4578H ;定义VALUE是变量
MOV AX,VALUE
或写成MOV AX,[VALUE]
;操作(AX)←(VALUE)
指令执行后,(AX)= 4578H
该指令源操作数的有效地址
EA = VALUE的偏移地址。

在直接寻址方式,若操作数不在数据段,必须使用跨段前缀,
如:MOV AX,ES:[3000H]
操作数在ES段,
EA = 3000H
MOV AX,SS:VALUE
VALUE是在SS段定义的变量。

一般用法:适用于处理单个变量。

4、寄存器间接寻址方式
操作数的有效地址在基址寄存器BX、BP或变址寄存器SI、DI中,操作数则在存储器中。

与段寄存器约定关系:
•若操作数在数据段,段地址在DS中
EA=(BX)
或者EA=(SI)
或者 EA=(DI )
•若操作数在堆栈段,段地址在SS 中
EA=(BP )
指令中不符合这个约定,必须使用跨段前缀。

例3.7 MOV AX ,[BX];操作(AX )←((BX )) 已知:(DS )= 2000H
(BX )= 1000H
物理地址 = 20000H + 1000H = 21000H 指令执行后,(AX )= 50A0H
例:指令MOV DX ,[BP]
则操作数在堆栈段,
物理地址 =(SS )×16+(BP )。

该指令将堆栈中的一个字数据传送到DX 寄存器。

使用SI 、DI 寄存器的寄存器间接寻址表示形式:
MOV AX ,[SI]
20000H 21000H 图3.4 例3.7执行情况 21001H AX
物理地址=(DS)×16 +(SI)
MOV AX,[DI]
物理地址=(DS)×16 +(DI)
允许使用段跨越前缀,操作数可以存放在其他段。

如:MOV AX,ES:[BX]
物理地址=(ES)×16 +(BX)
MOV AX,DS:[BP]
物理地址=(DS)×16 +(BP)
一般用法:适用于表格处理,执行完一条指令,只需修改寄存器内容,就可以取出表格中的下一项。

5、寄存器相对寻址方式(或称直接变址寻址方
式)
操作数的有效地址是一个基址或变址寄存器的内容和指令中指定的8位或16位位移量之和。

段寄存器的约定关系与寄存器间接寻址方式相同。

•若操作数在数据段,段地址在DS中
EA=(BX)+8位或16位位移量;
或者EA=(SI)+8位或16位位移量;
或者EA=(DI)+8位或16位位移量;
•若操作数在堆栈段,段地址在SS中
EA=(BP)+8位或16位位移量;
例3.9 MOV AX,COUNT [SI]
其中COUNT是在数据段中定义的符号,提供16位位移量。

物理地址=(DS)×16 + COUNT位移量+(SI)使用BX,DI的表现形式:
MOV AX,COUNT [BX]
MOV AX,COUNT [DI]
物理地址计算式中,只要将BX或DI值替换SI 值就可以了。

若COUNT是在堆栈段定义的符号地址,有指令:MOV AX,COUNT [BP]
物理地址=(SS)×16 + COUNT位移量+(BP)
允许使用段跨越前缀。

例如:MOV DL,ES:STRING [SI]
STRING是在ES段内定义的符号地址,提供16
位位移量。

物理地址=(ES)×16 + STRING位移量+(SI)
一般用法:适用于表格处理。

表格首地址由符号地址提供(例如上面二例中的COUNT,STRING),修改基址或变址寄存器内容,存取表格中的值。

6、基址变址寻址方式
操作数的有效地址是一个基址寄存器和一个变址寄存器内容之和,两个寄存器均由指令指定。

约定关系如下:
•若操作数在数据段,段地址在DS中
使用基址寄存器BX
EA=(BX)+(SI)
或者EA=(BX)+(DI)
•若操作数在堆栈段,段地址在SS中
使用基址寄存器BP
EA=(BP)+(SI)
或者EA=(BP)+(DI)
例3.10 MOV AX,[BX][DI]
或写为MOV AX,[BX+DI]
有效地址EA =(BX)+(DI)
物理地址=(DS)×16 +(BX)+(DI)
若有指令:MOV AX,[BP+SI]
有效地址EA =(BP)+(SI)
物理地址=(SS)×16 +(BP)+(SI)
使用注意点:在一条指令中,BX和BP不能同时寻址。

SI和DI不能同时寻址。

允许使用段跨越前缀。

例如:MOV AX,ES:[BX+SI]
有效地址:EA =(BX)+(SI)
物理地址=(ES)×16 +(BX)+(SI)
一般用法:用于表格和数组处理,首地址可放在BX或BP中,用SI或DI来访问数组中的各个元素,也即SI或DI中的值是表内索引。

由于二个寄存器值随时都可以修改,使用更加灵活。

常用于矩阵数组处理。

7、相对基址变址寻址
操作数的有效地址是一个基址寄存器的内容,一个变址寄存器的内容和指令中指定的位移量之和。

约定关系与基址变址寻址方式相同。

•若用基址寄存器BX,段地址在DS中,
EA=(BX)+(SI)+8位或者16位位移量或者EA=(BX)+(DI)+8位或者16位位移量•若用基址寄存器BP:段地址在SS中
EA=(BP)+(SI)+8位或者16位位移量或者EA=(BP)+(DI)+8位或者16位位移量例3.11 MOV AX,MASK [BX] [SI]
也可以写成:
MOV AX,MASK [BX+SI]
MOV AX,[MASK+BX+SI]
这条指令的三种写法,常用第二种写法。

有效地址:EA = MASK位移量+(BX)+(SI)物理地址=(DS)×16 + EA
其中:MASK是数据段内定义的符号地址。

若MASK是在堆栈段内定义的符号地址,
有指令语句:
MOV AX,MASK [BP+SI]
有效地址:EA = MASK位移量+(BP)+(SI)物理地址=(SS)×16 +EA
此时,BP可指向栈顶,从栈顶到数组首地址用MASK的位移量表示,SI用来访问数组中某个元素。

允许使用段跨越前缀。

寻址方式8、9和10均与比例因子有关,用于80386及其后继机型。

(略)
寻址方式综合举例:
把首地址为BLOCK的字数组的第6个字送到
DX 寄存器的指令序列。

首先在数据段定义BLOCK 数组,并且数据段段地址已经送入DS 寄存器中。

BLOCK DW 45H ,79H ,0BCH ,1256H ,0ACH ,
0F6H ,3400H ;定义七项
存储分配如图所示。

(1)用直接寻址
MOV DX ,BLOCK+10
(2)用寄存器间接寻址
MOV BX ,OFFSET BLOCK
第1个字 第2个字 第3个字 第4个字 第5个字 第6个字 第7个字 +2 +4 +6 +8 +10 +12
ADD BX,10
MOV DX,[BX];取数
其中语句OFFSET BLOCK是取变量BLOCK的偏移地址。

(3)用寄存器相对寻址
MOV BX,10 ;将第6个字离表首的位移
量放入BX
MOV DX,BLOCK [BX];取数
(4)用基址加变址寻址
MOV BX,OFFSET BLOCK;取BLOCK首地
址偏移量MOV SI,10 ;SI为表内索引MOV DX,[BX+SI] ;取数
3.1.2 与转移地址有关的寻址方式——在控制转移指令中介绍。

3.2 程序占有的空间和执行时间
1.程序装入内存需要占用存储空间
80X86 的机器指令是可变字节指令,不同的指令或者不同寻址方式的机器指令长度不同。

一条16位格式指令长度可为1—7字节,32位指令可达14
字节。

所以,程序装入内存需要占用存储空间,程序量越大,占有的存储空间也越大。

程序的机器代码也是一种数据,按字节存放。

2.程序运行需要时间
完成同样功能的不同程序,可能在占有存储空间和执行时间上有很大差别。

编程中,应该尽量在空间和时间上提高程序运行的效率,这就是程序的优化。

3.3 80X86的指令系统
80X86的指令系统可分为六大组:
数据传送指令串处理指令
算术运算指令控制转移指令
逻辑运算和移位指令性处理机控制指令。

教材中附录一80X86指令系统一览(P.435),表中所用符号说明如下:(见P.453 )
ac :累加器
mem:存储单元,可用任何存储器操作数寻址方式
reg:通用寄存器
data或imm:立即数
segreg:段寄存器
如其后跟以8、16、32,则表示其长度。

例如:IMM8 表示8位立即数
reg16 表示16位寄存器
标志位下各符号含义:
0—置0
1—置1,
X—根据结果设置,
一—不影响,
U—无定义
r—恢复原先保存的值
下面介绍16位指令,用于386及其后继机型的32位指令不在介绍。

一个纯16位模块程序应具有以下特征(P.192):(1)所有段长都小于或等于64K字节;
(2)数据项主要是8位或16位的;
(3)指向代码或数据的指针只有16位偏移地址;
(4)只在16位段之间控制
3.3.1 数据传送指令
一、通用数据传送指令
MOV 传送
PUSH进栈,POP出栈
XCHG交换
1、MOV 传送指令
格式:MOV DST,SRC
操作(DST)←(SRC)
DST:目的操作数
SRC:源操作数
此指令把一个字节或一个字操作数从源传送到目的。

传送结果:源操作数(SRC)保持不变;
目的操作数(DST)=(SRC),
DST中原值被覆盖。

MOV指令包括了全部七种寻址方式,指令可以有七种格式:
(1)MOV mem/reg1,mem/reg2
双操作数指令不允许两个操作数都使用存储器,二个操作数中必须有一个是寄存器。

具体形式是:
MOV reg1, reg2 操作:(reg1)←(reg2)MOV reg1, mem 操作:(reg1)←(mem)
MOV mem, reg2 操作:(mem)←(reg2)
例如:MOV AX,BX ;操作:(AX)←(BX)16位数据传送
MOV CL,AL ;操作:(CL)←(AL)
8位数据传送
MOV DX,[BX] ;寄存器←存储器
MOV MASK [BX+SI],CX ;存储器←寄存器
(2)MOV reg, data;(reg)←data
将立即数data赋给指定的寄存器,段寄存器除外。

立即数几种表示形式:
·各种数制的8位或16位常数
·字符的ASC II码
·用EQU表示的符号常量
·段地址和变量的偏移地址是16位立即数
例3.22 MOV BX,OFFSET TABLE
操作:把TABLE的偏移地址送到BX。

OFFSET:伪操作符
OFFSET TABLE意为取变量TABLE的偏移地址,操作结果是一个数值。

又例如:MOV CX,20;十进制数20送到CX MOV DH,10110001B
二进制操作数
例3.21 MOV DL,'E'
操作:字符E的ASC II码值送到DL
表1.3 常用字符的7位ASCII 值
(3)MOV ac, mem ;(ac)←(mem)将存储单元中的数据送到累加器
其中ac是累加器,具体是:
AX:16位累加器
AL或AH:8位累加器
例3.23 MOV AX,Y [BP] [SI]
传送的源操作数在堆栈中,其EA值是:
EA = (BP)+(SI)+Y的位移量
操作数的物理地址是:
(SS)×16 +(BP)+(SI)+ Y的位移量指令将该存储单元内容送到AX中。

又如:MOV AL,[BX]
MOV AX,ES:[BX+SI]
(4)MOV mem,ac ;(mem)←(ac)
累加器送存储单元。

例如:设ALPHA、ARRAY是数据段定义的变量有指令:MOV ALPHA,AX
MOV ARRAY [BX+SI],AL
MOV [BX],AL
三条指令都是将AX或AL值保存到内存中。

(5)MOV segreg, mem/reg
将存储器或寄存器中的值传送给段寄存器,CS 除外。

例3.20 MOV AX,DATA_SEG
MOV DS,AX
DATA_SEG是段名,代表段地址,是一个16位立即数。

段地址不能直接送段寄存器,必须通过AX 或其他16位通用寄存器传送。

例如:MOV ES,BX
MOV DS,[DI]
(6)MOV mem/reg, segreg
将段寄存器值传送到存储器或寄存器中。

segreg 可以使用CS,DS,ES,SS四个段寄存器中的任一个。

例如:MOV BX,ES ;(BX)←(ES)MOV SAVE,DS ;(SAVE)←(DS),
SAVE是变量MOV AX,CS ;(AX)←(CS)
(7)MOV mem, data (mem)←data
立即数送存储器
例如:MOV COUNT[SI],9CH
COUNT是数据段定义的变量
MOV 指令使用注意点:
(1)对8086/8088,操作数DST和SRC类型要一致,不能在不同的字长寄存器间传
送。

例:MOV BL,DX
这是一条错误的指令。

(2)立即数和CS寄存器不能作为目的操作数,立即数不能直接传送给段寄存器。

例如,下面三条指令语句是错误的:
MOV 45H,CL
MOV CS,AX
MOV DS,1000H
(3)二个mem操作数不能互传,
二个段寄存器之间也不能互传信息。

例如,下面指令是错误的:
MOV [BX],[SI]
MOV DS ,CS
(4)MOV 指令执行后不影响标志状态。

2、堆栈操作指令
堆栈特点:堆栈是内存中一个专用存储区,堆栈中数据结构是“后进先出”。

8086/8088堆栈:从高地址向低地址方向生长,
SS — 存放堆栈段段地址;
SP — 存放栈顶偏移地址
注意:SP 初值指向堆栈末地址的下一个地址。

堆栈指令:
(1) PUSH 进栈指令
格式:PUSH SRC
操作:(SP )←(SP )—2
高地址 栈底 低地址 堆栈初态 (
((SP)+1,(SP))←(SRC)
PUSH 指令四种格式:
PUSH reg 例:PUSH BX
PUSH mem 例:PUSH [BX]
PUSH segreg 例:PUSH CS
PUSH data
data 是立即数,在8086/8088 中不允许。

(2)POP出栈指令
格式:POP DST
操作:(DST)←((SP)+1,(SP))
(SP)←(SP)+2
POP 指令允许的格式:
POP reg 例:POP DX
POP mem 例:POP VALUE
POP segreg segreg不能用CS
例:POP DS ——正确
POP CS ——错误
注意:
(1)堆栈的存取必须以字为单位,操作数SRC、DST必须是字、双字或四字,可以用各种寻址方式,8086/8088中不能用立即数。

(2)PUSH 和POP 操作不影响标志位。

例3.29 PUSH AX
若指令执行前(SS )= 3000H
(SP )= 100H
(AX )= 2107H
指令执行情况如图3.10所示。

可见:指令执行后,AX 的高字节存入堆栈的高地址中,低字节存入低地址中,SS 值不变,SP
进栈方向 高地址 低地址 堆栈段 执行后 (SS (SP 堆栈段 执行前
(SS (SP 图3.10 PUSH AX 执行情况
值减2。

此时(SP )= 100H –2 = 0FEH ,
指向栈顶元素07H 。

例3.30 POP AX
若指令执行前(SS )= 3000H ,(SP )= 0FEH ,AX 值未知。

指令执行后,将栈顶元素07H 送入AL ,将栈顶地址加1单元内容送入AH ,
则(AX )= 2107H ,SS 值不变,SP 值加2, 此时(SP )= 0FEH + 2 = 100H
指令执行情况如图3.11所示。

出栈方向 高地址 低地址 执行后 (SS (SP
图3.11 POP AX 执行情况
执行前 (SS (SP
堆栈在汇编语言程序设计中起着重要的作用,它可以保存、恢复寄存器中的内容;在子程序和中断程序中,用堆栈保存返回地址,保护和恢复CPU 工作寄存器内容,形式如:
PUSH AX ;保护AX、BX内容
BX
;中间程序用到AX、BX POP BX ;恢复AX、BX原来内容
POP AX
3、交换指令XCHG
格式:XCHG OPR1,OPR2
操作:(ORP1) (OPR2)
该指令交换二个操作数的内容,二个操作数中,必须有一个在寄存器中,不允许使用段寄存器和立即数。

例3.34 XCHG BX,[BP+SI]
指令执行前:
(BX)= 6F30H,(BP)= 0200H,
(SI)= 0046H,(SS)= 2F00H,
字(2F246H)= 4154H
OPR2的物理地址:
2F000H + 0200H + 0046H = 2F246H
指令执行后:(BX)= 4154H
(2F246H)= 6F30H
又例如:XCHG SI,DI
指令执行前(SI)= 420AH,(DI)= 7955H
指令执行后(SI)= 7955H,(DI)= 420AH
二.累加器专用传送指令
输入指令IN(input)
输出指令OUT(output)
换码指令XLAT(Translate)
使特点:只限于使用累加器AX或AL传送信息。

IN、OUT指令在I/O程序设计中介绍
·换码指令XLAT
格式:XLAT OPR
或XLAT
操作:(AL)←((BX)+(AL))
功能:完成一字节查表,即用表中一字节数据来转换AL中的值。

OPR:表格首地址,一般为符号地址。

指令使用条件:
(1)在数据段建立换码表,表长最多256字节
(2)(BX )= 表首地址
(3)(AL )= 被转换值,该值应该是相对于表格
首地址的位移量。

3.39 如(BX )= 0040H ,(AL )= 0FH ,
(DS )= F000H ,
表格如图3.13所示。

执行指令 XLAT
转换单元物理地址:
(DS )×16+(BX )+(AL )
= F0000H + 0040H + 0FH = F004FH 。

指令执行后,将 F004FH 单元内容送到 AL 则 (AL )= 2CH
应用实例:
将0— F 的十六进制数转换为七段码管显示的
F004F F0040 (BX (AL 图3.13 例3.39所用的表格
显示代码。

在数据段建立换码表:
TABLE DB 40H,79H,24H,30H,…,06H,
0EH,共16项
表中各项依次是0-F的七段显示码值。

若要将十六进制数E转换成显示代码,指令语句是:
MOV BX,OFFSET TABLE ;(BX)=表首地址MOV AL,0EH ;(AL)= 被转换值XLAT TABLE(或)XLAT ;转换(AL)= 06H
三、地址传送指令
这组指令主要讲三条:
LEA REG,SRC ;有效地址送寄存器
LDS REG,SRC ;指针送寄存器和DS LES REG,SRC ;指针送寄存器和ES 说明:
指令中源操作数SRC必须是存储器操作数。

目的操作数REG是AX、BX、CX、DX、SI、DI、
SP、BP之一。

(1)LEA REG,SRC 有效地址送寄存器操作:(REG)←EA
用法:设置一个寄存器作为地址指针
例3.40 LEA BX,[BX+SI+0F62H]
若指令执行前:(BX)= 0400H,
(SI)= 003CH
指令执行后:
(BX)= (BX)+(SI)+ 0F62H
= 0400 +003C + 0F62 = 139EH
注意:这里BX寄存器得到的是偏移地址而不是该存储单元内容。

又例如:LEA DI,TABLE
指令执行前:(DI)= 508AH,
TABLE偏移地址为0046H
指令执行后:(DI)= 0046H
此指令将符号地址TALBLE的偏移地址(也即有效地址EA)送入DI中。

例3.41 LEA BX,LIST
MOV BX,OFFSET LIST
指出:在同一个源程序模块中,这二条指令功能等效。

但对指令LEA BX,[BX+SI] 不存在
等效的MOV传送指令。

(2)LDS REG,SRC指针送寄存器和DS 操作:(REG)←(SRC)
(DS)←(SRC+2)
把源操作数指定的4个相继字节送到由指令指定
寄存器及DS寄存器中。

该指令常指定SI寄存器。

例LDS SI,[10H]
如指令执行前:
(DS)= C000H (C0010H)= 0180H,(C0012H)= 2000H
则指令执行后:
(SI)= 0180H,(DS)= 2000H
分析:源操作数SRC是直接寻址,EA = 10H 物理地址=(DS)×16 + EA
= C0000 + 10 = C0010H
指令操作:(SI)←(C0010H)
(DS)←(C0012H)
(3)LES REG,SRC指针送寄存器和ES 操作:(REG)←(SRC)
(ES)←(SRC+2)
只要用ES去替换LDS指令中的DS,其他操作同LDS。

该指令常指定DI寄存器。

四、标志寄存器传送指令
本组共4条指令
(1)LAHF 操作:(AH)←(FLAGS的低字节)(2)SAHF 操作:(FLAGS的低字节)←(AH)
这二条指令操作对象是AH寄存器和FLAGS 寄存器低字节。

(3)PUSHF 标志进栈
操作:(SP)←(SP)- 2
((SP)+1,(SP))←(FLAGS)
(4)POPF 标志出栈
操作:(FLAGS)←((SP)+1,(SP))
(SP)←(SP)+2
PUSHF和POPF指令一般用于在子程序和中断处理程序首尾处,用以保护和恢复主程序运行结果的标志状态。

五.类型转换指令
(1)CBW 字节转换为字
格式:CBW
操作:将AL的符号扩展到AH,形成AX 中的字。

若(AL)中的D7 = 0,则(AH)= 00H;
若(AL)中的D7 = 1,则(AH)= 0FFH。

例如:MOV AL,95H ;AL最高有效位D7=1,CBW
指令执行后,(AX)= 0FF95H
(2)CWD 字转换为双字
格式:CWD
操作:将AX 的符号扩展到DX,形成DX:AX 中的双字。

若(AX)中的D15 = 0,则(DX)= 0000H;
若(AX)中的D15 = 1,则(DX)= 0FFFFH。

例如:MOV AX,8A00H ;AX最高有效位CWD D15 =1,
指令执行后,(DX)= 0FFFFH,(AX)= 8A00H 注意:CBW 和CWD 只适用于有符号数。

无符号数扩展方法:
·将AL扩展成AX:
MOV AH,0
·将AX扩展成DX、AX双字:
MOV DX,0
3.3.2 算术指令
80X86的算术运算指令包括二进制运算及十进制运算指令,执行加、减、乘和除运算。

有双操作数指令,也有单操作数指令。

寻址原则:
·单操作数指令不允许使用立即数方式和段寄存器。

·双操作数指令除源操作数是立即数情况以外,必须有一个操作数在寄存器中。

算术运算中二类数据:无符号数和带符号数
无符号数:将所有的数位都看成数据位,所以只有正数,没有负数。

带符号数:数据的最高位是符号位,数据本身用补码表示。

8位二进制数:
无符号数表示范围为0 —255
带符号表示范围为-128 —+127
16位二进制数:
无符号数表示范围0 —65535
带符号数表示范围-32768 —+32767 带符号数和无符号数的加减运算采用同一套指令,运算结果超出范围产生溢出;对于乘除运算,则分别有二套指令。

一、加法指令
·加法ADD DST,SRC
操作:(DST)←(DST)+(SRC)
·带进位加法ADC DST,SRC
操作:(DST)←(DST)+(SRC)+ CF
·加1 INC OPR
操作:(OPR)←(OPR)+ 1
说明:
·三条指令都可以作字或字节运算,386及其后继机还可进行双字操作。

·除INC指令不影响CF外,运算后都要建立条件标志。

条件标志中,最主的是CF、ZF、SF、OF四个标志位。

下面进一步分析CF和OF位设置。

一个8位或16位二进制数,在程序中既可认为是无符号数,也可以认为是带符号数,分析运算溢出有二个条件:
(1)加数和被加数都必须同时为无符号数或带符号数。

(2)程序中用检测不同标志位的方法区别这二类数运算结果是否溢出。

这二个条件同样适用于减法运算。

8位二进制数加法运算溢出情况分析:P.60(4) 87H + 0F5H = 7CH
执行后CF = 1 OF = 1
SF= 0 ZF = 0
AF = 0 PF = 0
二种情况和都超范围,溢出。

分析:
·看作无符号数相加
87H = 135
F5H = 245
135 + 245 = 380 = 256 + 124
相加后的和为 7CH = 124
将进位CF=1以28 = 256 为权值考虑在内,得到的和是正确的,和为9 位二进制数.
·看作带符号数相加
87H = -121
F5H = -11
87H + F5H = (-121) + (-11) =-132
因为–132 小于-128 超出范围,产生负溢出, 使和成为正数7CH,结果错误。

结论:
·CF = 1,表示无符号数运算产生溢出,此时不属于出错,CF所保存的进位值是有用的。

在多字节运算中,利用CF位传递低位字节向高位字节的进位。

·OF = 1,表示带符号数运算溢出,结果错误。

例3.45 ADD DX,0F0F0H
操作:(DX)←(DX)+(F0F0H)
说明:立即数用十六进制书写,若第一个数是字母,前面必须加“0”,保证语法正确。

若指令执行前(DX)= 4652H
加法运算:
4652H + F0F0H = 3742H
指令执行后
(DX)= 3742H,
ZF = 0 SF = 0
CF = 1 OF = 0
看作带符号数相加,DX值是正数,F0F0H 是负数,正数加负数,和不会溢出。

例3.46 二个双精度数(双字长数)的加法运算设目的操作数在DX、AX中,DX存放高位字
源操作数在BX、CX中,BX存放高位字。

操作如下图:
加数
加数

15
15
+
分析:一个双字长数,高位字的最高位是符号位,低位字是无符号数,加法运算先加二个低位字,然后用CF传送进位。

双字加法指令序列为:
ADD AX,CX ;(AX)←(AX)+(CX)
低位字相加
ADC DX,BX ;(DX)←(DX)+(BX)+ CF
高位字带进位加
最终的标志位状态由ADC指令执行结果决定。

二、减法指令
·减法SUB DST,SRC
操作:(DST)←(DST)―(S RC)
·带借位减法SBB DST,SRC
操作:(DST)←(DST)―(SRC)―CF
·减1 DEC OPR
操作:(OPR)←(OPR)―1
·求补N EG OPR
操作:(OPR )← ―(OPR )
或写成(OPR )←0 ―(OPR )
求补运算也是将操作数按位求反后末位加1,算式如下:
8位数求补: (OPR )← 0FFH ―(OPR )+ 1 16位数求补:(OPR )←0FFFFH ―(OPR )+ 1
·比较 CMP OPR1,OPR2
操作:(OPR1)―(OPR2)
比较指令CMP 只执行减法运算,不保存结果,只是根据结果设置条件标志位,供其后的条件转移指令判断,实现程序分支。

减法运算中的CF 和OF 标志

·CF标志:反映二个无符号数相减的借位情况。

当减数>被减数,有借位,CF = 1
减数≤被减数,无借位,CF = 0
·OF标志:反映有符数相减溢出情况。

同号数相减,不会溢出,OF = 0;
异号数相减,差的符号位与减数相同,OF = 1。

例3.48 SUB [SI+14H],0136H
如指令执行前(DS)= 3000H,(SI)= 0040H,
(30054H)= 4336H
指令执行的操作是:
(30054H)←(30054H)– 0136H
4336H – 0136H = 4200H
机内运算:(P.63)
将减数取补后执行加法,最后将进位求反。

所以指令执行结果:
(30054H)= 4200H
SF = 0 ZF = 0 CF = 0 OF = 0。

例3.49 SUB DH,[BP+4]
指令执行前
(DH)= 41H
(SS)= 0000H
(BP)= 00E4H
(000E8H)= 5AH
指令执行操作是:
(DH)←(DH)―(000E8H)
减法运算:41H―5AH = E7H
运算结果:(DH)= 0E7H
各标志状态:
减数>被减数,需借位,CF = 1
二数相减差不为“0”,ZF = 0
差的最高位D7 = 1,SF = 1,负数
差中有偶数个“1”位,PF = 1
二个正数相减不会溢出,OF = 0
例3.50 设X、Y、Z均为双精度数,它们分别存放在地址为X,X+2;Y,Y+2;Z,Z+2的存储单元中,存放时高位字在高地址中,低位字在低地址中。

编制程序段实现下列算式:
W ←X + Y + 24 – Z
运算结果存入W,W+2单元
编程注意点:
(1)双精度数就是双字长数,每项占 4 个字节。

二个存储器数不能直接加减,必须先取一个
数到寄存器后再实行运算。

(2)低位字用一般的加减指令,高位字用带进位的加减指令。

(3)本例中全部用直接寻址方式。

工作程序如下:
MOV AX,X ;(AX)←X低位字
MOV DX,X+2 ;(DX)←X高位字
ADD AX,Y ;X、Y低位字相加
ADC DX,Y+2 ;X、Y高位字带进位加ADD AX,24 ;加24
ADC DX,0 ;进位传递
SUB AX,Z ;减Z的低位字
SBB DX,Z+2 ;减Z的高位字
MOV W,AX ;存入结果底位字
MOV W+2,DX ;存入结果高位字
X+1
X+2
X+3
Y
三、乘法指令
1、无符号数乘法指令MUL
格式:MUL SRC
执行的操作:
字节乘:(AX)←(AL)*(SRC)
字乘:(DX,AX)←(AX)*(SRC)
2、带符号数乘法指令IMUL
格式:IMUL SRC
执行的操作与MUL相同,但必须是带符号数。

乘法指令操作数:
目的操作数必须是累加器(隐含),字运算为AX,字节运算为AL;
源操作数SRC可以使用寄存器或存储器操作数,立即数和段寄存器除外。

相关文档
最新文档