256个字节。
5)字位扩展指令
字位扩展指令完成操作数的扩展,一种是将一个字节的数扩展为字,另一种是将一个字的数扩展为双字,以满足各种特殊需要(以后要用到)。
(1)CBW(convert byte to word)指令
指令格式为: CBW
CBW指令将一个字节操作数扩展为一个字长的数,源操作数隐含在AL中,目标操作数隐含在AX中。当(AL)<80H时,(AH)= 00H;否则(AH)= FFH,即为有符号数的扩展。
CBW指令应用举例:
例:把字节数8EH扩展为字。 程序如下: MOV
CBW
AL,8EH
执行结果:(AX)= FF8EH。
(2)CWD(convert word to double word)指令
CWD指令将一个字操作数扩展为双字,源操作数隐含在AX中,目标操作数隐含在DX和AX中。当(AX)<8000H时,(DX)= 0000H;否则(DX)= FFFFH,也为有符号数的扩展。
CWD指令应用举例:
例:把字43FFH扩展为双字。 程序如下:
MOV AX,43FFH CWD
执行结果:(DX):(AX)= 000043FFH
2.输入输出(I/O)指令
(I/O)指令是专门用于向输入输出端口进行读写操作的指令。有IN和OUT两条指令。需要特别指出的是只有累加器AL(或AX)才能与I/O端口进行数据传送,所以这两条指令也称为累加器专用传送指令。
8088系统可连接多个外设端口。在8088的I/O指令中,只允许用两种寻址方式:
·直接寻址方式:指令中包含一个8位的由立即数提供的I/O端口地址。允许寻址256个端口,端口地址范围为00H~FFH。 ·寄存器间接寻址方式:端口地址规定由DX寄存器指定,可寻址64K个端口(地址范围为0000H~FFFFH)。 (1)输出指令IN(input) 指令格式为: IN
acc,port
;直接寻址,port为8位立即数表示的端口地址
IN acc,DX ;间接寻址,DX的内容为16位端口地址
上述指令从端口输入一个字节到AL或输入一个字到AX中,具体有以下四种形式。 IN IN 个
IN
AL,DATA AX,DATA
AL,DX
;端口地址8位,输入一个字节到AL
;端口地址8位,由DATA和DATA + 1两个端口输入一;字到AX中
;端口地址16位,由(DX)端口输入一个字节到AL中
31
IN
AX,DX ;端口地址16位,由(DX)和(DX)+ 1两个端口输入
;一个字节到AX中 输入指令IN应用举例。
例:从地址为03B0H的端口输入一个字节到AL。 程序如下: MOV IN
DX,03B0H AL,DX
;将16位端口地址送DX
;从地址为03B0H的端口输入一个字节到AL(说明)
(2)输出指令OUT(output) 指令格式为: OUT OUT OUT OUT
OUT OUT 1
port,acc DX,acc DATA,AL DATA,AX
DX,AL DX,AX
;直接寻址,port为8位立即数表示的端口地址 ;间接寻址,DX的内容为16位端口地址
;端口地址8位,由AL输出一个字节到DATA端口
;端口地址8位,由AX输出一个字到DATA和DATA + 1 ;两个端口
;端口地址16位,由AL输出一个字节到(DX)端口 ;端口地址16位,由AX输出一个字到(DX)和(DX)+ ;两个端口
上述指令把AL(或AX)的内容输出到指定的端口,具体有以下四种形式:
输出指令OUT应用举例。
例:将AX的内容从地址为0043H和0044H的两个端口输出。 程序如下:
MOV DX,0043H OUT DX,AX
3.地址传送指令
8088/8086指令系统提供3条用于传送地址的指令:LEA、LDS、LES。 (1)取偏移地址指令LEA(load effective address) 指令格式为: LEA reg16,mem
LEA指令将存储器的16位偏移地址送到指定的寄存器,这里源操作数必须是存储器操作数,而且传送的是偏移地址。目标操作数是16位通用寄存器,而该寄存器用来作地址指针。
LEA指令应用举例。
例:将内存单元BUFFER和BUFFER + 1两个单元的内容送AX。 程序如下: LEA MOV MOV
BX,BUFFER AL,[BX]
AH,[BX + 1]
;将内存单元BUFFER的偏移地址送BX ;BUFFER单元内容送AL
;BUFFER + 1单元内容送AH
;端口地址0043H送DX
;将AX的内容从地址为0043H和0044H的两个端口输出
上2、3条指令也可合为MOV AX,[BX]。
又例:设(BX)= 1000H,(DS)= 6000H,(61050H)= 33H,(61051H)= 44H。试述执行下述两条指令后的结果。
LEA BX,[BX + 50H] MOV BX,[BX + 50H]
32
解:第一条指令执行后(BX)= 1050H;
第二条指令执行后(BX)= 4433H(见P.115图3-14) 从此例可以说明MOV指令和LEA指令的不同之处。 (2)指令LDS(load point into DS) 指令格式为 LDS
reg16,mem32
;(reg16)←(mem32 + 1):(mem32) ;(DS)←(mem32 + 3): (mem32 + 2)
LDS指令源操作数mem32为存储器操作数,给出的是内存中4个连续单元的首地址,目
标操作单元有两个。一个为reg16,是BX、BP、SI、DI四个间址寄存器之一,存放上述4个存储单元的前两个单元内容作偏移地址。另一个操作单元为隐含的DS,存放上述4个存储单元的后两个单元内容作段基址。
LDS指令应用举例:
例:设(DS)= 6OOOH,内存地址为60348H开始的4个单元存放了一个32位的远指针98011H(作解释),如P.116图3-15所示。试析执行下两条指令的结果。
LDS
MOV
SI,[0348H] AX,[SI]
执行结果:(SI)= 8011H,(DS)= 9000H,(AX)= 3412H。 (3)指令LES(load point into ES) 指令格式为: LES
reg16,mem32
;(reg16)←(mem32 + 1):(mem32) ;(ES)←(mem32 + 3): (mem32 + 2)
LES指令和LDS指令相仿,仅将DS换成ES而已。例见P.116。
4.标志传送指令
标志传送指令共有4条:LAHF、SAAHF、PUSHF、POPF。 (1)LAHF(load AH with flag)指令 指令格式为:
LAHF
该指令把标志寄存器低8位(含SF、ZF、AF、PF、CF五个标志位)传送到AH的对应位,如P.116图3-16所示。指令执行对标志位无影响。
(2)SAHF(store AH into flag)指令 指令格式为:
SAHF
SAHF指令与LAHF指令执行相反的操作,即将AH中的7、6、4、2、0位内容传送到标志寄存器的SF、ZF、AF、PF、CF位,以改变对应标志位的状态,但其它标志位不受影响。
LAHF指令和SAHF指令一般配对使用。
(3)PUSHF和POPF指令
该两条指令实质上为堆栈操作指令,只不过其操作数为标志寄存器FLAGS而已,操作功能类同堆栈操作指令。
PUSHF和POPF指令用于过程调用时保护标志位的状态。PUSHF和POPF指令一般配对使用。
3.3.2算术运算指令
算术运算指令包括加、减、乘、除四组。可实现字节或字,无符号数和有符号数运算。
33
指令有单操作数(如乘、除指令)的,也有双操作数的。单操作数不允许使用立即数,而双操作数中,立即数也只能作为源操作数。此外,也不允许两个操作数都为存储器操作数。
算术运算可能涉及到超出数的表示范围的问题,对无符号数和有符号数分别可由CF和OF标志来判断。
除四组二进制算术运算指令外,为使运算结果为十进制数(为BCD码),8088指令系统还提供了四类十进制调整指令。
算术运算指令大多会对标志位产生影响。 1.加法运算指令
加法运算指令有三条:不带进位位的加法指令ADD、带进位位的加法指令ADC及加1指令INC。
(1)不带进位位的加法指令ADD(add) 指令格式为:
ADD OPRD1,OPRD2
;(OPRD1)←(OPRD1)+(OPRD2)
ADD指令用于两个操作数相加(目标操作数加源操作数),和置于目标操作单元。
源操作数和目标操作数均可为8位或16位的寄存器操作数或存储器操作数,源操作数还可为立即数。两操作数可为无符号数,也可为带符号数。
需要注意的是:两操作数不能同时为存储器操作数。另外不能对段寄存器进行运算。 ADD指令的执行会对6个状态标志位产生影响。
例如:
ADD CL,20H
;(CL)←(CL)+ 20H
ADD AX,SI ;(AX)←(AX)+(SI)
ADD DATA[BX],AL ;((BX)+ DATA)←((BX)+ DATA)+(AL) ADD DX,[BX+SI] ;(DX)←(DX)+((BX)+(SI)+ 1):((BX)+(SI)) 上述指令均为合法的ADD指令,而下列ADD指令则是非法的: ADD ADD
[SI],[BX] DS,AX
;不允许两操作数均为存储器操作数 ;不允许段寄存器进行运算
ADD指令应用举例:
例:试析执行下列指令后,各标志位的状态。 MOV AL,7EH ;(AL)←7EH ADD
AL,5BH 01111110
;(AL)←7EH + 5BH
+ 01011011
11011001
执行后:AF = 1,CF = 0,OF = 1,PF = 0,SF = 1,ZF = 0
(AL)= D9H
若为无符号数,运算结果未超出8位二进制数的表示范围(CF = 0); 若为有符号数,运算结果已超出8位二进制数的表示范围(OF = 1)。 (2)带进位的加法指令ADC(add with carry) 指令格式为:
ADD OPRD1,OPRD2
;(OPRD1)←(OPRD1)+(OPRD2)+ CF
ADD指令在格式、功能及对标志位影响上都与ADD指令类同,只是标志位CF的值也参
与加法运算,常用于多字节加法运算。
ADC指令应用举例:
34
例:求两个4字节无符号数0107A379H + 10067E4FH之和。 程序如下:
MOV DX,0107H MOV AX,0A379H MOV BX,1006H MOV ADD
CX,7E4FH AX,CX
;第1个数的高位送DX ;第1个数的低位送AX ;第2个数的高位送BX ;第2个数的低位送CX ;两数低16位相加
ADC DX,BX ;两数高16位相加,并加上低16位相加中的进位位 执行结果:(DX)= 110EH (AX)= 21C8H CF = 0
即两数之和为110E21C8H
上程序可简化如下: MOV ADD MOV
AX,0A379H AX,7E4FH DX,0107H
ADC DX,1006H
执行结果与上程序相同。
(3)加1指令INC(increment) 指令格式为: INC OPRD ;(OPRD)←(OPRD)+ 1
INC指令将指定的操作数内容加1,后再送回该操作数。操作数可以是寄存器或存储器操作数。但不能是段寄存器,也不能为立即数。操作数可以是8位,也可为16位。 INC指令不影响CF标志位,但对AF、OF、PF、SF及ZF会产生影响。它通常在循环程序中用于修改地址指针及循环次数等。
例如: INC AX ;(AX)←(AX)+ 1
INC INC
BL
BYTE PTR[SI]
;(BL)←(BL)+ 1
;将SI所指向的存储单元内容加1,并送回该单元
2.减法指令
8088/8086共有5条减法指令。包括:不考虑借位的减法指令SUB,考虑借位的减法指令SBB,减1指令DEC,求补指令NEG以及比较指令CMP。
(1)不考虑借位的减法指令SUB(subtract)
指令格式为:
SUB OPRD1,OPRD2
;(OPRD1)←(OPRD1)-(OPRD2)
SUB指令用于两个数相减(目标操作数减去源操作数),结果置于目标操作单元。
该指令对操作数的要求及对标志位的影响与ADD指令完全相同。 例如: SUB SUB
BL,30H
AL,[BP + SI]
;(BL)←(BL)- 30H
;AL的内容减去SS段中偏移地址为(BP)+ (SI)单元的
;内容,结果送AL
(2)考虑借位的减法指令SBB(subtract with borrow)
指令格式为:
SBB OPRD1,OPRD2 ;(OPRD1)←(OPRD1)-(OPRD2)- CF
SBB指令在格式、功能及对标志位的影响上与SUB指令类同,只是标志位CF的值也参
35