80X86汇编语言程序设计_8086_8088寻址方式和指令系统解析

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

80X86汇编语言程序设计
第二章8086/8088寻址方式和指令系统(3~20)
一.8086/8088寄存器组:
(14个16位寄存器,8个8位寄存器)
1.数据寄存器:AX(AH.AL). AX和AL是累加器。

用累加器进行计算操作时间最短。

BX(BH.BL). BX又叫基址寄存器。

唯一作为存储器指针的寄存器。

CX(CH.CL). CX控制循环的次数。

CL保存移位的位数。

DX(DH.DL). DX用于做32位乘除法时,存放被除数或保留余数。

2.指针寄存器:SP堆栈指针. 保存堆栈指针栈顶地址。

BP基址指针.
3.变址寄存器:SI源地址.
DI目的地址.
变址和指针寄存器主要用于存放某个存储单元地址的偏移,或某组存储单元开始地址的偏移,即作为存储器指针使用。

通用寄存器由数据寄存器.指针寄存器.变址寄存器构成。

4.控制寄存器:IP指令指针. 指令指针IP给出接着要执行的指令在代码段中的偏移。

FLAG标志寄存器.包含了9个标志,主要用于反映处理器的状态和运算结果的某些特征。

(1)运算结果标志
进位标志CF(Carry F);零标志ZF(Zero F);符号标志SF(Sign F);溢出标志OF(Over F);奇偶标志PF(1的个数为偶数,则PF被置1);辅助进位标志AF;
(2)状态控制标志
方向标志DF;中断允许标志IF;跟踪标志TF。

5.段寄存器:CS代码段.
DS数据段.
SS堆栈段.
ES附加段.
二. 存储器分段和地址的形成:
1.存储单元的地址和内容
地址是用二进制数来表示的,它是无符号整数,书写格式为十六进制数。

16位二进制数可以表示2的16次方,也就是0~65535的地址范围。

65536个字节单元的存储容量是64K。

一个存储单元中存放的信息成为该存储单元的内容。

字单元的地址采用它的低地址来表示,并采用“高高低低”的原则。

四个连续的字节单元就构成了一个双字单元。

2.存储器地址的分段及物理地址的形成
8086/8088 CPU有20根地址线,可直接寻址的物理地址为2的20次方也就是1M字节(用16进制数表示1M字节的地址范围是00000~FFFFF)。

所以,要访问1M字节空间的存储器必须有20位地址。

CPU采用存储器地址分段的办法来提供20位地址。

从0地址开始,每16个字节为一小段(16的倍数)。

IBMPC机对段的起始地址有所限制,段不能起始于任意地址,而必须从任一小段的首地址开始。

在16进制表示的地址中,最低位是0(即20位地址的低4位为0)。

{00000,00010,00020,00030,…000F0,…FFFE0,FFFF0,}
­在1M字节的存储器里,每一个存储单元都有一个唯一的20位地址。

称为:该存储单元的物理地址。

把存储单元的地址与所在段的起始地址的差称为段内偏移,称为偏移。

在整个1M地址空间中,存储单元的物理地址等于段起始地址加上偏移。

物理地址=段*16+偏移
20位物理地址=16位段地址+16位偏移地址。

指令中不使用物理地址,而是使用逻辑地址,由总线接口单元BIU按需要根据段值和偏移自动形成20位物理地址。

3.段寄存器的引用
计算机在取指令的时候,自动引用代码段寄存器CS,再加上由IP所给出的16位偏移,得到要取指令的物理地址。

当涉及到一个堆栈操作时,则自动引用堆栈寄存器SS,再加上由SP所给出的16位偏移,得到堆栈操作所需要的物理地址。

当偏移涉及BP寄存器时,缺省引用段寄存器SS。

在存取一个普通存储器操作数时,则自动选择数据寄存器DS或附加段寄存器ES,再加上16位偏移,得到存储器操作数的物理地址。

三.8086/8088的寻址方式:
计算机是通过执行指令序列来解决问题的,因而每种计算机都有一组指令集提供给用户使用,这组指令集就称为计算机的指令系统。

计算机中的指令由操作码字段和操作数字段两部分组成。

汇编语言是一种符号语言,它用助记符来表示操作码,用符号或符号地址来表示操作数或操作数地址。

它与机器指令一一对应。

寻址方式:表示指令中用于说明操作数所在的地址的方法
8086/8088有七种基本的寻址方式,下面介绍这七种寻址方式:
1.立即寻址方式
操作数就包含在指令中,它作为指令的一部分,跟在操作码后存放在代码段。

(源操作数)这种操作数称为立即数。

例如:指令:mov ax,1234H
mov al,5
mov bx,3064H
2.寄存器寻址方式
操作数在CPU内部的寄存器中,指令指定寄存器号。

对于16位操作数,寄存器可以是:AX.BX.CX.DX.SI.DI.SP.BP等。

对于8位操作数,寄存器可以是:AH.AL.BH.BL.CH.CL.DH.DL等。

这种寻址方式由于操作数就在寄存器中,不需要访问存储器来取得操作数,因而可以取得较高的运算速度。

例如:mov ax,bx
mov si,ax
mov al,dh
3.直接寻址方式
操作数在寄存器中,指令直接包含有操作数的有效地址(偏移地址)。

操作数一般存放在数据段。

所以操作数的地址由DS加上指令中直接给出的16位偏移得到。

例如:mov ax,[8054] DS=2000H
在汇编语言指令中,可以用符号地址代替数值地址
例如:mov ax,[value]
mov ax,value
如value在附加段中,则应指定段超越前缀如下:
mov ax,es:value
mov ax,es:[value]
直接寻址方式常用于处理单个寄存器变量的情况。

它可以实现在64K字节的段内寻找操作数。

直接寻址的操作数通常是程序使用的变量。

注意立即寻址和直接寻址书写表示方法上的不同,直接寻址的地址要放在方括号中。

在源程序中,往往用变量名表示。

4.寄存器间接寻址方式
操作数在存储器中,操作数有效地址在SI.DI.BX.BP这四个寄存器之一种。

在一般情况下,如果有效地址在SI.DI.BX中,则以DS段寄存器之内容维断指。

如果有效地址在BP中,则以SS段寄存器之内容为段值。

例如:mov ax,[si] (DS)=5000H (SI)=1234H
指令中叶可指定段超越前缀来取得其他段中的数据如:
mov ax,es:[bx] mov [si],ax
mov [bp],cx mov si,ax
5.寄存器相对寻址方式
操作数在存储器中,操作数的有效地址是一个基址寄存器(BX.BP)或变址寄存器的(SI.DI)内容加上指令中给定的8位或16位位移量之和。

即:
EA(有效地址)=BX.BP.SI.DI+8位(16位)位移量
在一般情况下,如果SI.DI.BX之内容作为有效地址的一部分,那么引用的段寄存器是DS。

如果BP之内容作为有效地址的一部分,那么引用的段寄存器是SS。

例如mov ax,[di+1223H] DS=5000H, DI=3678H
物理地址=50000+3678+1223=5489BH
mov bx,[BP-4]
mov es:[BX+5],AL
指令mov ax,[SI+3]与mov ax,3[SI]是等价的。

6.基址加变址寻址方式
操作数在存储器中,操作数的有效地址由:基址寄存器之一的内容与变址寄存器之一的内容相加
即:
EA=BX BP+SI DI
在一般情况下,如果BP之内容为有效地址的一部分,则以SS之内容为段值,否则以DS 之内容为段值。

例如mov ax,[BX][DI]
mov ax,ES:[BX+SI]
这种寻址方式适用于数组或表格处理。

下面两种表示方法是等价的:
mov ax,[BX+DI]
mov ax,[DI][BX]
7.相对基址加变址寻址方式
操作数在存储器中,操作数的有效地址由:基址寄存器之一的内容与变址寄存器之一的内容及指令中给定的8位或16位位移量相加得到。

即:
EA=BX BP+SI DI+8位或16位位移量
在指令中给定的8位或16位位移量采用补码形式表示。

在计算有效地址时,如果位移量是8位,那么被带符号扩展成16位。

当所得的有效地址超过FFFFH时,就取其64K的模。

例如mov ax,[BX+DI-2]
相对基址加变址这种寻址方式的表示方法多种多样,下面四种表示方法均是等价的:
mov AX,[BX+DI+1234H]
mov AX,1234H[BX+DI]
mov AX,1234H[BX][DI]
mov AX,1234H[DI][BX]
四.8086/8088指令系统
8086/8088的指令系统可分为如下六个功能组:
1.数据传送;
2.算术运算;
3.逻辑运算;
4.串操作;
5.程序控制;
6.处理器控制.
汇编语言中指令语句的一般格式。

指令语句可由四部分组成,一般格式如下:
【标号:】指令助记符【操作数1【,操作数2】】【;注释】
(一)数据传送指令
1.传送指令
格式:MOV DST,SRC
源操作数(SRC)可以是累加器(Al.AH).寄存器.存储单元以及立即数,而目的操作数(DST)可以是累加器.寄存器和存储单元,不能是立即数。

传送不改变源操作数。

数据传送指令能实现下列传送功能:
(1)CPU内部寄存器之间的数据传送。

例如:MOV AH,AL
MOV DL,DH
MOV BP,SP
MOV AX,CS
注意:源操作数和目的操作数不能同时是段寄存器(CS.SS.DS.ES)代码段寄存器CS不能作为目的操作数,指令指针IP既不能作为源操作数,也不能作为目的操作数。

注意,这种例外永远存在。

(2)立即数送至通用寄存器或存储单元。

例如:MOV AL,3
MOV SI,-5
MOV V ARB,-1 ;V ARB是变量名,代表一个存储单元
MOV V ARW,3456H ;V ARW是一个字变量
MOV [SI],6543H
注意:立即数不能直接传送到段寄存器。

立即数永远不能作为目的操作。

(3)寄存器与存储器间的数据传送。

例如:MOV AX,V ARW ;V ARW是一个字变量,存储器操作为直接寻址。

MOV AX,[0123]
MOV BH,[DI] ;存储器操作数位寄存器间接寻址
MOV DI,ES:[SI+3] ;存储器操作数为相对变址寻址,使用段超越前缀
MOV V ARB,DL ;V ARB是一个字节变量
MOV DS:[BP],DL ;使用段超越前缀
MOV V ARW,DS ;V ARW是一个字变量
MOV ES,V ARW
注意:源操作数和目的操作数类型要一致。

即同时为字节或字,不能一个字节,另一个是字。

除了串操作指令外,源操作数和目的操作数不能同时是存储器操作数。

两个操作数必须有一个寄存器(立即寻除外)。

例如:把字变量V ARW1的内容送到字变量V ARW2
MOV AX,V ARW1
MOV V ARW2,AX
这种利用通用寄存器过度的方法,也适用于段寄存器间的数据传送。

例如:MOV AX,CS
MOV DS,AX ;把CS的内容送到DS
MOV AL,'D'
立即数(字符D的ASCII码44H)送到AL寄存器。

MOV BX,OFFSET TABLE
把TABLE的偏移地址(不是内容)送到BX寄存器,其中OFFSET为属性操作符。

例如:BX=1234H BP=5678H要交换两个寄存器的内容。

用MOV指令如下:MOV AX,BX
MOV BX,BP
MOV BP,AX
利用交换指令可方便地实现通用寄存器与通用寄存器或存储单元间的数据交换。

2.交换指令
格式:XCHG OPRD1,OPRD2
此指令把操作数OPRD1的内容与操作数OPRD2的内容交换。

操作数同时是字节或字。

例如:XCHG AL,AH
XCHG SL,BX
OPRD1和OPRD2可以是通用寄存器和存储单元。

但不包括段寄存器,也不能同时是存储单元,还不能有立即数,可采用各种存储器寻址方式来制定存储单元。

例如:XCHG BX,[BP+SI] 如指令执行前:
(BX)=6F30H, (BP)=0200H, (SI)=0046H, (SS)=2F00H, (2F246)=4154H
物理地址=SS*16+BP+SI=2F000+0200+0046=2F246H
指令执行后:(BX)=4154H (2F246H)=6F30H
注意:使用BP的时候,段地址是SS堆栈段。

3.地址传送指令
(1)指令LEA (传送偏移地址)(Load Effective Address)
格式:LEA REG,OPRD
指令LEA称为传送有效地址指令。

该指令把操作数OPRD的有效地址传送到操作数REG。

操作数OPRD必须是一个存储器操作数,操作数REG必须是一个16位的通用寄存器。

例如:LEA AX,BUFFER ;BUFFER是变量名
LEA DS,[BS+S]
LEA SI,[BP+DI+4]
LEA BX,[BX+SI+0F62H]
如指令执行前(BX)=0400H,(SI)=003CH
指令执行后(BX)=0400+003C+0F62=139EH
(2)指令LDS(传送32位地址指针)(Load pointer into DS)
格式:LDS REG,OPRD
段值和段内偏移构成32位的地址指针。

该指令传送32位地址指针。

执行的操作:(REG)←(SRC)
(DS)←(SRC+2)
该指令把操作数OPRD中所含的一个32位地址指针的段值部分送到数据段寄存器DS,把偏移部分送到指令给出的通用寄存器REG。

操作数OPRD必须是一个32位的存储器操作数,操作数REG可以是一个16位的通用寄存器,但实际使用的往往是变址寄存器或指针寄存器。

例如:LDS SI,POINTER ;POINTER是一个双字变量
假设双字变量POINTER 包含的32位地址指针的段值为5678H,偏移为1234H,那么在执行指令后:
(DS)=5678H ,(SI)=1234H
32位地址指针的偏移部分存储在双字变量的低地址字中,段值部分存储在高地址字中。

例如:LDS SI,[10H]
如指令执行前:(DS)=C000H, (C0010H)=0180, (C0012H)=2000H
指令执行后:(DS)=2000H, (SI)=0180H.
SRC=DS*16+10H=C0000+10=C0010H
SRC+2=C0010+2=C0012H
(3)指令LES
格式:LES REG,OPRD
指令LES也传送32位地址指针,该指令把操作数OPRD中所含的32位地址指针的段值部分送到附加段寄存器ES,把偏移部分送到指令给出的通用寄存器REG。

执行的操作:(REG)←(SRC)
(ES)←(SRC+2)
例如:LES DI,[BX]
如指令执行前:(DS)=B000H (BX)=080AH (0B080AH)=05AEH (0B080CH)=4000H
指令执行后:(ES)=4000H (DI)=05AEH
例如:TABLE为数据段中0032单元的符号名,其中存放的内容为1234H,试问以下三条指令有什么区别?指令执行完后AX寄存器的内容是什么?
MOV AX,TABLE (AX)=1234H
LEA AX,TABLE (AX)=0032H
MOV AX,OFFSET TABLE (AX)=0032H
例如:一个有16个字的数据区,它的起始地址为70A0:DDF6。

请写出这个首末数据字单元的物理地址。

(首地址)=70A00+DDF6=7E7F6H
16个字=32个字节,是十进制,换算成16进制是20H。

但是从首地址到末地址中间是30个字节也就是1E。

(末地址)=7E7F6+1E=7E814H
4.堆栈操作指令
在8086 8088系统中,堆栈是一段RAM区域。

称为栈底的一端地址较大(高地址),称为栈顶的一端地址较小(低地址)。

堆栈的段值在堆栈段寄存器SS中,堆栈指针寄存器SP始终指向栈顶。

堆栈是以“后进先出”方式工作的一个存储区。

堆栈的存取必须以字为单位。

堆栈操作指令分为两种:
(1)进栈指令PUSH
格式:PUSH SRC
执行的操作:(SP)←(SP)-2
该指令把源操作数SRC压入堆栈。

它先把堆栈指针寄存器SP的值减2,然后把源操作数SRC送入由SP所指的栈顶。

源操作数SRC可以是通用寄存器和段寄存器,也可以是字存储单元。

例如:PUSH AX
(2)出栈指令POP
格式:POP DST
执行的操作:(SP)←(SP)+2
该指令从栈顶弹出一个字数据到目的操作数DST。

它先把堆栈指针寄存器SP所指的字数据送至目的的操作数DST,然后SP值加2。

DST可以是通用寄存器和段寄存器(但CS例外),也可以是字存储单元。

注意:以上两条指令PUSH和POP只能做字操作。

它们可以使用除立即数以外的其他寻址方式。

但POP指令不允许用CS寄存器。

下面的程序段说明堆栈的一种用途,临时保存寄存器的内容,必要时再恢复其原始内容。

例如:PUSH AX ;保护AX
PUSH BX
……;其间程序用到AX和BX寄存器
POP BX ;使DS得内容与CS的内容相同
POP AX ;恢复AX
例如:PUSH SI POP SI
PUSH DS POP ES
PUSH V ARW ;V ARW是字变量POP V ARW ;V ARW是字变量
PUSH [SI] POP [SI]
通过上面讲过的指令,数据交换有三种方式:
传送指令MOV
交换指令XCHG
堆栈指令PUSH POP
例如:将寄存器AX和SI的内容交换
用MOV指令,利用通用寄存器过度的方法
MOV BX,AX
MOV AX,,SI
MOV SI,BX
用交换指令XCHG
XCHG AX,SI
用堆栈指令
PUSH AX
PUSH SI
POP AX
POP SI
5.标志操作指令
(1)标志传送指令
①指令LAHF
格式:LAHF
该条指令把标志寄存器的低8位(包括SF、ZF、AF、PF和CF)传送到寄存器AH的指定位。

②指令SAHF
格式:SAHF
该条指令与LAHF刚好相反,把寄存器AH的指定位送至标志寄存器低8位的SF、ZF、AF、PE和CF标志位。

FLAG:0位是CF;2位是PF;4位是AF;6位是ZF;7位是SF;8位是TF;9位是IF;10位是DF;11位是OF。

例如:MOV AH,0C1H
SAHF
指令执行前:AH=1100 0001
指令执行后:CF=1,PF=0,AF=0ZF=1,SF=1.
③指令PUSHF
格式:PUSHF
该条指令把标志寄存器的内容压入堆栈,即先把堆栈指针寄存器SP的值减2,然后把标志寄存器的内容送入由SP所指的栈顶。

④指令POPF
格式:POPF
该条指令把当前堆栈顶的一个字传送到标志寄存器,同时相应地修改堆栈指针,即把堆栈指针寄存器SP的值加2.
这条指令和PUSHF指令一起可以保存和恢复标志寄存器的内容,即保存和恢复各标志的值。

另外,这两条指令也可以用来改变追踪标志TF。

(2)标志位操作指令
①清进位标志指令CLC
格式:CLC
该指令使进位标志为0。

也就是说CF=0。

②置进位标志指令STC
格式:STC
该指令使进位标志为1。

也就是说CF=1。

③进位标志取反指令CMC
格式:CMC
该指令使进位标志取反。

如CF为1,则使CF为0;如CF为0,则CF为1。

④清方向标志CLD
格式:CLD
该条指令使方向标志DF为0。

从而在执行串操作指令时,使地址按递增方式变化。

⑤置方向标志STD
格式:STD
该条指令使方向标志DF为1。

从而在执行串操作指令时,使地址按递减方式变化。

⑥清中断允许标志CLI
格式:CLI
该条指令使中断允许标志IF为0。

于是CPU就不响应来自外部装置的可屏蔽中断。

但对不可屏蔽中断和内容中断都没有影响。

⑦置中断允许标志STI
格式:STI
该条指令使中断允许标志IF为1,则CPU可以响应可屏蔽中断。

(二)加减运算指令
1.加法指令ADD
格式:ADD OPRD1,OPRD2
执行的操作:(OPRD1)←(OPRD1)+(OPRD2)
例如:MOV AX,7896H ;AX=7896H
即AH=78H AL=96H ;各标志位保持不变
ADD AL,AH ;AL=AL+AH=96H+78H(=10EH)=0EH 前面的1给了进位标志CF。

即AH=78H, AX=780EH
CF=1 PF=0 AF=0 ZF=0 SF=0 OF=0
例如:ADD DX,0F0F0H
执行前(DX)=4652H
执行后(DX)=4652H+F0F0H(=13742H)=3742H 前面的1给了进位标志CF。

ZF=0 SF=0 CF=1 OF=0
这里4的二进制码是0100,F是1111,一个正数一个负数相加肯定OF是0。

例如:ADD AX,4321
执行前(AX)=62A0H
执行后(AX)=62A0+4321=A5C1H 这里要注意,A的二进制数是1010,最高有效位为1,所以SF为1。

两个正数相加,结果为负的就溢出;两个负数相加,结果为正的就溢出。

SF=1 ZF=0 CF=0 OF=1
这里6的二进制码是0110,而4的二进制码是0100,两个正数相加,结果A为1010为负,所以OF为1。

从上面例子可看出:加法指令影响标志位。

OF位根据操作数的符号及其变化情况来设置:若两个操作数的符号相同而结果的符号与之相反时OF=1,否则OF=0。

CF位可以用来表示无符号数的溢出。

由于无符号数的最高有效位只有数值意义而无符号意义,所以从该位产生的进位应该是结果的实际进位值,但在有限数的范围内就说明了结果。

2.带进位加指令ADC
格式:ADC OPRD1,OPRD2
执行的操作:(OPRD1)←(OPRD1)+(OPRD2)+(CF)
例如:下列指令序列执行两个双精度(32位)的加法。

设目的操作数放在DX和AX寄存器中,其中DX存放高位字,源操作数存放在BX、CX中,其中BX存放高位字。

(双精度的
数高位和高位相加,低位和低位相加,首先加低位。


如指令执行前:(DX)=0002H (AX)=0F365H (BX)=0005H (CX)=0E024H 指令序列为:ADD AX,CX
ADC DX,BX
执行第一条指令后:
(AX)=AX+CX=F365+E024)=1D389)=D389H
SF=1 ZF=0 CF=1 OF=0
这里F的二进制是1111,E的二进制是1110,得出的D是1101。

所以OF为0。

(8以上全是负的,8以下全是正的)
执行第二条指令后:
(DX)=DX+BX+CF=0002+0005+0001=0008H
SF=0 ZF=0 CF=0 OF=0
则该指令序列执行完后:(DX)=0008H (AX)=D389H
从上面的例子可以看出:
为实现双精度加法,必须用两条指令分别完成低位字和高位字的加法,而且在高位字相加时,应该使用ADC指令以便把前一条ADD指令作低位字加法所产生的进位值加入高位字之内。

另外,带符号的双精度数的溢出,应该根据ADC指令的OF位来判断,而作低位加法用的ADD指令的溢出是无意义的。

此指令影响标志位。

3.加1指令INC
格式:INC OPRD
这条指令完成对操作数OPRD加1,然后把结果送回OPRD,即:
(OPRD)←(OPRD)+1
操作数OPRD可以是通用寄存器,也可以是存储单元。

这条指令执行的结果影响标志ZF、SF、OF、PF和AF,但它不影响CF。

该指令主要用于调整地址指针和计数器。

例如:写出把首地址为BLOCK的子数组的第6个字送到DX寄存器的指令。

要求使用以下几种寻址方式:
(1)寄存器间接寻址
MOV BX,OFFSET BLOCK ;首先把BLOCK里的偏移地址送给BX ,这里也可以用LEA BX,BLOCK
ADD BX,000AH
MOV DS,[BX]
(2)寄存器相对寻址
MOV BX,OFFSET BLOCK
MOV DX,[BX]000AH]
4.减法指令SUB
格式:SUB OPRD1,OPRD2
执行的操作:(OPRD1)←(OPRD1)-(OPRD2)
例如:SUB [SI+14H],0136H
指令执行前(DS)=3000H,(SI)=0040H,(30054H)=4336
物理地址=DS+SI+14H=30000+0040+0014=30054H SUB(30054H)=4336-0136=4200H 指令执行后(30054H)=4200H
SF=0 ZF=0 CF=0 OF=0
例如:SUB DH,[BP+4]
指令执行前(DH)=41H, (SS)=0000H, (BP)=00E4H, (000E8H)=5AH
SS:BP=00000+00E4+4=000E8 =5AH
SIB DH-BP=41H-5AH=E7H
指令执行后(DH)=0E7H
SF=1 ZF=0 CF=1 OF=0
此指令影响标志位CF位说明无符号数想减的溢出,同时它又是被减数的最高有效位向高位的借位值。

OF位则说明带符号数的溢出。

减法的OF位的设置方法为:若两个数的符号相反,而结果的符号与减数相同则OF=1。

说明结果是错误的。

5.带借位减指令SBB
格式:SBB OPRD1,OPRD2
执行的操作:(OPRD1)←(OPRD1)-(OPRD2)-CF
例如:SBB AL,DL
SBB DX,AX
该指令主要用于多字节数相减的场合。

6.减1指令DEC
格式:DEC OPRD
执行的操作:(OPRD)←(OPRD)-1
例如:DEC V ARB ;V ARB是字节变量
操作数OPRD可以是通用寄存器,也可以是存储单元。

在相减时,把操作数作为一个无符号数对待。

这条指令执行的结果影响标志ZF、SF、OF、PF和AF,但不影响CF。

7.取补指令NEG
格式:NEG OPRD
执行的操作:(OPRD)←0-(OPRD)
这条指令对操作数取补,就是用零减去操作数OPRD,再把结果送回OPRD。

(各位取反末尾加1)操作数可以是通用寄存器,也可以是存储单元。

例如:NEG AL
NEG V ARW[SI] ;有效地址就是V ARW的位移加SI的值
如在字节操作时对-128取补,或在字操作时对-32768取补,则操作数不变,但OF被置1。

其它均为0。

此指令的执行结果影响CF、ZF、SF、OF、AF和PF,操作数为0时,求补运算的结果使CF=0,其它情况则均为1。

8.比较指令CMP
格式:CMP OPRD1,OPRD2
这条指令完成操作数OPRD1减去操作数OPRD2,运算结果不送到OPRD1。

但影响标志CF、ZF、SF、OF、AF和PF。

例如:CMP SI,DI
CMP CL,5
CMP DX,[BP-4]
比较指令主要用于比较两个数的关系,是否相等,谁大谁小。

执行了比较指令后,可根据ZF是否置位,判断两者是否相等;如果两者是无符号数,则可根据CF判断大小;如果两者是有符号数,则要根据SF和OF判断大小。

遇到双精度数用AX存放低字,用DX存放高字。

先进行低字的加减法,再进行高字的加减法,因为在高位还要算入带进位的加减法。

例如:写出对存放在DX和AX中的双字长数求补的指令序列
答案:NEG DX
NEG AX
SBB DX,0
如果是双字数进行求补,首先对高位(DX)进行求补,然后再对低位(AX)求补、求补:用0减或者各位取反末尾加一。

(三)乘除运算指令
乘除运算指令分为无符号数运算和有符号数运算指令,这点与加减法运算指令不同。

乘除运算指令对标志位的影响有些特别
1.乘法指令
在乘法指令中,一个操作数总是隐含在寄存器AL(8位数相乘)或者AX(16位数相乘)中,另一个操作数可以采用除立即数方式以外的任一种寻址方式。

(1)无符号数乘法指令MUL
格式:MUL OPRD
在乘法指令里,目的操作数必须是累加器。

两个8位数相乘得到的是16位乘积存放在AX 中,两个16位数相乘得到的是32位乘积存放在DX、AX中,DX存放高位字,AX存放低位字。

如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不等于零,则标志CF=1,OF=1,否则CF=0,OF=0。

所以如果CF=1和OF=1表示在AH或DX中含有结果的有效数。

(2)有符号数乘法指令IMUL
格式:IMUL OPRD
这条指令把被乘数和乘数均作为有符号数,此外与指令MUL完全类似。

如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不是低半部分的符号扩展,则标志CF=1,OF=1;否则否则CF=0,OF=0。

所以如果CF=1和OF=1表示在AH或DX中含有结果的有效数。

该指令对其他标志位无定义。

例如:如(AL)=0B4H,(BL)=11H求执行指令
IMUL BL
MUL BL后的乘积值。

执行IMUL BL的结果为(AX)=0FAF4H=-1292D CF=OF=1 有符号数用FFB4*11或转换成二进制,如果AX中的高半部分AH不是FF,这里是FA,则CF=OF=1。

执行MUL BL的结果为(AX)=OBF4H=3060D CF=OF=1 无符号数用B4*11
2.除法指令
在除法指令中,被除数总是隐含在寄存器AX(除数是8位)或者DX和AX(除数是16位)中,另一个操作数可以采用除立即数方式外的任一种寻址方式。

(1)无符号数除法指令DIV
格式:DIV OPRD
字节操作表示为:(AL)←(AX)/(OPRD)的商:(AH)←(AX)/(OPRD)的余数
字操作表示为:(AX)←(DX,AX)/(OPRD)的商;(DX)←(DX,AX)/(OPRD)的余数
如果除数为0,或者在8位数除时商超过8位。

或者在16位除时商超过16位,则认为是除溢出,引起0号中断。

除法指令对标志位的影响无定义。

(2)有符号数除法指令IDIV
格式:IDIV OPRD
这条指令把被除数和除数均作为有符号数,此外与指令DIV完全类似。

当除数为0,或者商
太大(字节除时超过127,字除时超过32767),或者商太小(字节除时小于-127,字除时小于-32767)时,则引起0号中断。

例如:设(AX)=0400H,(BL)=0B4H,即(AX)为无符号数的1024D,带符号数的1024D (BL)为无符号数的180D,带符号数的-76D
执行DIV BL的结果是:
(AH)=7CH=124D余数
(AL)=05H=5D 商
执行IDIV BL的结果是:
(AH)=24H=36D余数
(AL)=0F3H=-13D商
3.符号扩展指令
由于除法指令隐含使用字被除数或双字被除数,所以当被除数为字节,或者除数和被除数均为字时,需要在除操作前扩展被除数。

为此8086 8088专门提供了符号扩展指令。

(1)字节转换为字指令CBW
格式:CBW
这条指令把寄存器AL中的符号扩展到寄存器AH。

例如:MOV AX,3487H ;AX=3487H,即AH=34H,AL=87H CBW ;AH=0FFH,AL=87H,即AX=0FF87H
这条指令不影响各标志位。

(2)字转换为双字指令CWD
格式:CWD
这条指令把寄存器AX中的符号扩展到寄存器DX。

例如:MOV AX,4567H ;AX=4567H
CWD ;AX=4567H,DX=0
该指令不影响标志位。

AL和AX中最高有效位是0~7位为正数,则AH和DX扩展为00;
AL和AX中最高有效位是8~15位为负数,则AH和DX扩展为FF。

(四)逻辑运算和移位指令
1.逻辑运算指令
(1)否操作指令NOT
格式:NOT OPRD
这条指令把操作数OPRD取反,然后送回OPRD。

操作数OPRD可以是通用寄存器,也可以是存储器操作数,不能是立即数。

此指令对标志位没有影响。

例如:MOV AL,03H
NOT AL
指令执行后:(AL)=0FCH
(2)与操作指令AND
格式:AND OPRD1,OPRD2
这条指令对两个操作数进行按位的逻辑“与”运算,结果送到目的操作数OPRD1。

该指令执行以后,标志CF=0,标志OF=0,标志PF、ZF、SF反映运算结果,标志AF未定义。

某个操作数自己与自己相“与”,则值不变,但可使进位标志CF清0。

与操作指令主要用在使一个操作数中的若干位维持不变,而另外若干位清为0的场合。

把要维持不变的这些位于“1”相“与”,而把要清为0的这些位于“0”相“与”就能达到这样的目的。

相关文档
最新文档