740 likes | 1.08k Views
第三章 8086/8088 的指令系统. 第一节 寻址方式. 一、立即寻址. 二、寄存器寻址. 三、直接寻址. 四、寄存器间接寻址. 五、变址寻址. 六、基址加变址寻址. 第二节 指令系统. 一、数据传送指令. 二、算术运算指令. 三、逻辑运算指令. 四、串操作指令. 五、控制转移指令. 六、处理器控制指令. 第三章 8086 的寻址方式和指令系统. 3 - 1 8086 的寻址方式.
E N D
第三章 8086/8088的指令系统 第一节 寻址方式 一、立即寻址 二、寄存器寻址 三、直接寻址 四、寄存器间接寻址 五、变址寻址 六、基址加变址寻址 第二节 指令系统 一、数据传送指令 二、算术运算指令 三、逻辑运算指令 四、串操作指令 五、控制转移指令 六、处理器控制指令
第三章 8086的寻址方式和指令系统 3-1 8086的寻址方式 计算机的指令一般由操作码和操作数组成,操作码规定了指令的功能;而操作数则规定了指令操作的对象。操作数可以以立即数的形式存放在指令中,但在大多数情况下,操作数是以地址的形式存放在指令(指示操作数在哪儿)。用于说明操作数所在地址的方法称为寻址方式。 在微机中,操作数存放在: 1、在指令中;2、在CPU的某一内部寄存器中;3、在内存的数据区中;4、I/O端口。 在8086CPU中,内存地址是由数据段地址和段内偏移量组成。而指令中规定的地址即为段内偏移量(逻辑地址)——有效地址EA,有效地址EA构成的方法不同,则为不同的寻址方式。
操作码 操作数 ... 操作数 指令: 操作码字段:用助记符表示,表示指令执行什么样的操作。 操作数字段:用符号或符号地址表示,指操作数本身、操作数地址或操作结果送到哪里去。 单操作数 操作数 双操作数:源操作数和目的操作数 无操作数 例:单操作数指令:INC AX DEC CX 双操作数指令:MOV AX, [2000H] ADD AH, BL 无操作数指令: HLT、NOP
M AH AL AX 操作码 码段 imL imH 一、立即寻址方式(Immediate Addreing) 例:MOV AX,im MOV AL,26H 操作数(8位或16的常数)直接包含在指令中,紧跟在操作码后面,与操作码一起放在代码段区域中。操作数im既可是8位的,也可是16位的。 注:1.立即数不能做目的数; 2.立即数的长度不能超过目的空间长度 imH imL
AX DS 二、寄存器寻址(Register Addreing) 操作数放在指令规定的寄存器中。 例:MOV DS,AX 注:目的与源操作数长度相等
操作码 码段 00 20 数据段 30000 32000 32001 50 30 AL AH 三、直接寻址方式(Direct Addreing) 操作数的有效地址EA是指令的一部分,它与操作码一起放在代码段区域中。 操作数的物理地址为数据段寄存器DS加上16位地址偏移量。 物理地址= DS*16+ EA 例:若(DS)=3000H MOV AX,[2000H] 指令中存储单元的地址也可用符号地址表示。 例:AREA1 DW 0867H MOV AX,AREA1 注意区分: AREA1 EQU 0867H MOV AX,AREA1 30 50
操作码 码段 数据段 20000 21000 21001 A0 50 AX AL AH 四、寄存器间接寻址方式(Register Indirect Addreing) 操作数在存储单元中。操作数的有效地址EA在指令码所指定的寄存器中。可作为间址的寄存器有SI、DI、BX、BP, 若: 1、操作数在数据段DS中:则以寄存器BX、SI或DI间接寻址。 2、操作数在堆栈段中:则以寄存器BP间接寻址。 物理地址= DS*16+ SI(DI、BX) 或 = SS*16+ BP 例:若(DS)=2000H,(SI)=1000H MOV AX,[SI] 50 A0
操作码 操作码 码段 00 30 数据段 30000 35000 35001 50 30 AX 五、寄存器相对寻址方式(Register Relative Addreing) 操作数在存储单元中。操作数的有效地址是以指令指定的寄存器内容加上指令中给定的8位或16位位移量。 若指令指定的寄存器是BX、SI或DI,段寄存器使用DS; 若指令指定的寄存器是BP, 则段寄存器使用SS。 例:若(DS)=3000H, (SI)=2000H,COUNT=3000H MOV AX,COUNT [SI] 或 MOV AX, [COUNT +SI] 物理地址=16×DS+SI+COUNT =30000H+2000H+3000H =35000H 物理地址= DS*16+ SI(DI、BX)+DISP 或 = SS*16+ BP+DISP 30 50
六、基址变址寻址方式(Based Indexed Addreing) 操作数在存储单元中。操作数的有效地址是一个基址寄存器(BX或BP)和一个变址寄存器(SI或DI)的内容之和,两个寄存器均由指令指定。一般由基址寄存器决定所使用的段寄存器。 若指令指定的寄存器是BX,段寄存器使用DS; 物理地址=16×DS+BX+SI 或 =16×DS+BX+DI 若指令指定的寄存器是BP, 则段寄存器使用SS。 物理地址=16×SS+BP+SI 或 =16×SS+BP+DI 例:MOV AX ,[BX][SI] 若 DS=3000H,SI=2000H,BX=3000H,(35000H)=0ABCDH 则:物理地址=16×DS+BX+SI=35000H AX=0ABCDH
七、相对基址变址寻址方式(Relative Based Indexed Addreing) 操作数在存储单元中。操作数的有效地址是基址寄存器(BX或BP)内容加上变址寄存器(SI或DI)的内容、再加上指令中指定的8位或16位位移量。一般由基址寄存器决定所使用的段寄存器。 若指令指定的寄存器是BX,段寄存器使用DS; 物理地址=16×DS+BX+SI+8位或16位位移量 或 =16×DS+BX+DI +8位或16位位移量 若指令指定的寄存器是BP, 则段寄存器使用SS 物理地址=16×SS+BP+SI +8位或16位位移量 或 =16×SS+BP+DI +8位或16位位移量 例: MOV AX,COUNT [BX] [SI] 若 DS=3000H,SI=0300H,BX=1500H, COUNT =0200H,(31A00H)=26BFH 则:物理地址=16×DS+BX+SI+ COUNT = 31A00H AX=26BFH
需说明的几个问题 1、指令中使用方括号的地址表达式必须遵循下列规则: * 立即数可以出现在方括号内,表示直接地址; * 只有SI、BP、DI、BX可以出现在方括号内,它们可以单独出现,也可以相加后出现,或以寄存器与立即数相加的形式出现,但BX和BP或SI和DI不能同时出现在同一个[ ]内,SI和DI也不能同时出现; * 方括号有相加的含义,下面几种写法都是等价的: 1200[BX][SI] [BX+1200][SI] [BX+ SI +1200] * 方括号内包含BP,则隐含使用SS提供基地址;其余情况均使用DS提供基地址。
2、段超越: 在8088系统中,数据通常在数据段中,但若需要,数据也可存放在代码段,堆栈段以及附加段中,这种情况就是段超越。应用时,需在指令中加以说明。 例: MOV AX, DS:[BP] 例:MOV AX,ES:[0500H] ES表示数据在附加段中; : 是修改属性运算符。
3、其它寻址方式 (1)隐含寻址:指令中不指明操作数 (2)I/O端口寻址:8086有直接端口寻址和间接端口寻址两种方式,端口寻址范围分别为0-0FFH和0-FFFFH。 (3)转移类指令寻址 (4)一条指令有几种寻址方式
数据传送 算术运算 逻辑运算 一、数据传送指令 串操作 (一)通用传送指令 控制传送 处理器控制 1、 MOV OPRD1,OPRD2 目的操作数 源操作数 立即数 通用指针变址寄存器 存储器 段寄存器 DS、ES、SS 3-2 8086的指令系统 8088的指令系统可以分为六个功能组: MOV指令允许传送数据的途径如下图所示 功能:将源操作数的一个字节(B)或一个字(W)传送到目的操作数所指的单元。 说明:* 指令中至少要有一项明确指出传送的是字节还是字; * 可用不同的寻址方式; * 不影响标志位; * 源操作数不变; *存储器之间,立即数与段寄存器,段寄存器之间不能用一条指令完成数据传送。
2、堆栈操作指令 操作:PUSH 操作时,先修改SP 的值,使 SP 2 SP 后,把源操作数(字)压入堆栈中 SP 指示的位置上。OPRD可以是16位的通用寄存器,段寄存器,存储器中的字。 指令执行前 AX=2A8CH SP 2000: 0130H 2000: 0000H 堆栈是以“ 先进后出”的方式工作的一个存储区, 进栈指令 PUSH OPRD 功能:将一个字的源操作数传送至由SP所指向的堆栈的顶部. 例:PUSH AX指令执行过程: 指令执行后 AX=2A8CH 2000: 0130H SP 2AH 8CH 2000: 012EH SP 2000: 0000H
出栈指令 POP OPRD 72H 72H 39H 39H 6EH 6EH 功能:把当前 SP 所指向的堆栈顶部的一个字送到指定的目的操作数中。(CS不能作为目的操作数) 操作:每执行一次出栈操作,SP +2 → SP ,指向新的栈顶。 例:设SS=2000H,SP = 0130H,(20130H)= 396EH,BX=4FAEH,执行指令POP BX的过程如下图所示: 执行指令前BX=4FAEH 执行指令后BX= 39 6EH 2000: 0132H SP → 2000: 0131H SP → SP → 2000: 0130H 2000: 0130H 2000: 0000H 2000: 0000H
3、交换指令 指令格式:XCHG OPRD1,OPRD2功能:把一个字或一个字节的源操作数与目的操作数交换。 交换可在寄存器之间、寄存器与存储器之间进行。 但段寄存器不能作为操作数,也不能直接交换两个存储单元中的内容。 例:设AX=31B0H,DS=3000H, BX=1800H,(31800H)= 1995H,执行指令 XCHG AX, [BX]的过程为: 执行指令后 执行指令前 AX 1995H 31B0H AX 19H 31H 31801H 31801H 95H B0H 31800H 31800H
(二)累加器专用传送指令1、输入指令 IN 执行指令前 80H端口 5BH 9DH 80H端口 17H 5BH 81H端口 22H 17H 81H端口 AX AX 3355H 9DH 指令格式: IN AL,n或 IN AX,n;n为 255 的端口地址 IN AL,DX 或 IN AX,DX;端口地址放在DX中。 第一种格式,端口地址n(00~FFH)直接包含在IN指令里,共允许寻址256个端口。当端口地址号大于FFH时,必须用第二种寻址方式,即先将端口号送入DX寄存器,再执行输入操作。 功能:从8位端口读入一个字节到AL,或从16位端口读入一个字到AX。 例:用IN指令从输入端口读取数据 (2) IN AX,80H (1) IN AL,0E3H 执行指令后 执行指令前 E3H端口 AL 执行指令后 E3H端口 5BH 17 9DH AL
2、输出指令 OUT 指令格式: OUT n ,AL或 OUT n ,AX OUT DX,AL或 OUT DX,AX 执行指令后 执行指令前 执行指令后 执行指令前 AX 3F46H AX 3F46H AL AL 9AH 9AH 端口 端口 端口 端口 84H 85H 84H 85H 66H 300H 300H 22H 77H 功能:将AL中的一个字节写到一个8位端口,或把AX中的一个字写到一个16位端口。 例:用 OUT 指令对输出端口进行操作 2) MOV DX,300H OUT DX,AL 1) OUT 84H,AX 46H 9AH 3FH
3、换码指令 XLAT (查表指令) 功能:((BX)+(AL))→AL 指令格式:XLAT 该指令执行前,先把转换表首地址的偏移量送入BX中,而把要查找表内单元的偏移量(0~255)送入AL中。执行换码指令后,把该单元的内容送入AL中。 例:若十进制数字0~9 的 LED七段显示码对照表已存放在内存中,表格的首地址为TABLE,用 XLAT 指令求数字5的七段显示码值程序如下: TABLE DB 40H, 79H, 24H, 30H, 19H DB 12H, 02H, 78H, 00H, 18H ; 建立七段显示码表格 5 MOV AL,5 ; AL MOV BX,OFFSET TABLE ; BX 表格首地址 XLAT ; AL 12H
(三)地址-目的传送指令 这是专用于传送地址码的指令,可用来传送操作数的段地址和偏移地址,共包含以下三条指令: 1、LEA取有效地址指令 指令格式:LEA r , src 功能:把源操作数的地址偏移量,传送至目的操作数。 要求源操作数必须是一个内存操作数;目的操作数必须是一个除段寄存器以外的16位寄存器。 指令 LEA BX,TABLE 与指令 MOV BX,OFFSET TABLE是等价的 例:SI=1000H,DS=5000H,(51000H)=1234H 执行指令 LEA BX, [SI]后,BX=1000H 执行指令 MOV BX, [SI]后,BX=1234H
2、LDS将双字指针送指令指定的寄存器和DS指令 指令格式:LDS r,src 功能:从源操作数指定的存储单元中的双字指针送到指令指定的寄存器(常指定SI)及DS寄存器中。 例:设DS=1200H,(13450H)=3F46H,(13452H)=0A92H 执行指令 LDS SI,[ 1450H ]后: SI = 3F46H, DS = 0A92H
3、LES将双字指针送到寄存器和ES指令 指令格式:LES r,src 功能:从源操作数指定的存储单元中的双字指针送到指令指定的寄存器(常指定DI)及ES寄存器中。 例:设DS=0100H, BX=0020H, (01020H) =0300H, (01022H)= 0500H, ES= 3000H. 执行指令 LES DI,[ BX ]后 DI = 0300H, ES = 0500H
2、SAHF AH送标志寄存器指令 指令格式:SAHF 操作示意图 15 12 11 10 9 8 7 6 5 4 3 2 1 0 FLAG O D I T S Z A P C AH (四)标志寄存器传送指令 1、LAHF 标志送到 AH指令 指令格式:LAHF 功能:把标志寄存器中的 SF、ZF、AF、PF和CF分别送到AH寄存器的位7、6、4、2和 0,位5、3、1的内容未定义。 功能:把寄存器AH中的 7、6、4、2、0位传送到标志寄存器的SF、ZF、AF、PF和 CF位,高位标志 OF、DF、IF 和 TF不受影响。
3、PUSHF 标志入栈指令 指令格式:PUSHF 功能:修改堆栈指针,使SP 2 → SP,把整个标志寄存器的内容压入堆栈,指令执行后对标志位无影响。 4、POPF 标志出栈指令指令格式:POPF 功能:把当前堆栈指针 SP 所指的一个字,传送给标志寄存器,并修改堆栈指针,使 SP +2 → SP 。 在过程(子程序)调用和中断服务程序中,可用PUSHF和POPF指令来保护和恢复标志位。另外,这两条指令也可用来改变追踪标志 TF (入栈,修改,出栈)(8088无直接改变T标志的指令)。
把内存中首地址为me1的200字节送到地址为me2的内存中。把内存中首地址为me1的200字节送到地址为me2的内存中。 Mov si,offset mem1 Mov di,offset mem2 Mov cx , 200 Mov [si],al Mov al,[di] Inc si Inc di Dec cx Jnz next Me1->si me2-> di 200->cx [si]->al,al->[di] Si++,di++,cx-- Cx =0 Over
(一)加法指令 1、ADD OPRD1,OPRD2 2、ADC OPRD1,OPRD2 功能:OPRD1+OPRD2+CF OPRD1 二、算术运算指令 8088指令系统提供了加、减、乘、除四种基本运算指令,可处理无符号或带符号的8位或16位二进制数的算术运算(带符号数是用补码表示)。还提供了各种调整操作指令,故可进行压缩的或非压缩的十进制数的算术运算。绝大部分算术运算指令都影响状态标志位。 功能:将源和目的操作数相加,结果送到目的操作数中,即 OPRD1+OPRD2 OPRD1 这两条指令的源操作数OPRD2可以是寄存器、存储器或立即数,目的操作数OPRD1只能用寄存器和存储单元。注意,源操作数和目的操作数不能同时为存储器,而且它们的类型必须一致,即都是字节或字。它们影响的标志位为:CF、OF、PF、SF、ZF和AF。
例:设,(AX)= 7365H, (BX)=1025H, (CX)=0E024H (DX)=0102H 执行指令 ADD AX,CX;(AX)=5389H ,CF=1 ADC DX,BX;(DX)=1128H ,CF=0 结果: (AX)=5389H , (DX)=1128H,(BX)=1025H,(CX)=0E024H 标志位 SF =0, ZF =0, CF =0, OF =0, AF =0 3、INC OPRD增量指令(单操作数) 功能:对目的操作数加1,结果送回目的操作数。即OPRD+1→ OPRD。目的操作数可以在通用寄存器或内存中。 指令执行后影响AF、OF、PF、SF和ZF,但不影响CF。 例:对内存单元的内容加1必须说明该单元的类型 INC BYTE PTR[BX] INC WORD PTR[BX] 例:INC BL INC CX
4、AAA 未组合BCD码加法调整指令 功能:在用ADD或ADC指令对两个未组合BCD码作加法后,运算结果已存在AL中,用AAA指令对AL中的数据进行调整,产生一个未组合的十进制和放在AX中。 例:实现两个未组合十进制数加法运算。设AL = 08H , BL = 07H ADD AL,BL; AL = 0FH AAA ; AX = 0105H 未组合十进制数的和放在AX中 5、DAA组合BCD码加法调整指令 功能:将两个组合BCD码相加后,存放在AL中的结果,调整为正确的组合BCD数。 DAA指令要紧跟在ADD或ADC指令之后使用,以实现组合的十进制数加法运算。 。 例:实现两个组合十进制数加法运算。设AL =28H, BL =68H 执行 ADD AL,BL; AL = 90H, CF = 0, AF = 1 DAA ; AL+06HAL,AL = 96H 结果 AL = 96H, CF = 0, AF = 0
设置循环计数器 0送CF,0送SI 取加数送AL 被加数+加数送DATA2 修改循环次数及指针 N 加完 Y 结束 例:求两个多字节无符号数之和。加数在DATA1开始的单元中,被加数在DATA2开始的单元中,字节长度为5,和存放在DATA2中。 源程序段: 程序框图: MOV CX,5 MOV SI,0 CLC LOP: MOV AL,DATA1[SI] ADC DATA2[SI],AL INC SI DEC CX JNZ LOP HLT
(二)减法指令 1、SUB OPRD1,OPRD2 功能:OPRD1 OPRD2 OPRD1 2、SBB OPRD1,OPRD2功能:OPRD1 OPRD2 CF OPRD1 这两条指令均影响AF、CF、OF、PF、SF和ZF 3、DEC OPRD减量指令 功能:OPRD 1 OPRD 执行后不影响CF,但影响 AF、OF、PF、SF和ZF 4、NEG OPRD取负指令 功能:0 OPRD OPRD 指令执行后影响AF、CF、OF、PF、SF和 ZF。若字节操作数为80H(128),字操作数为8000H(32768),执行NEG指令后操作数无变化,但OF =1。如操作数为0,执行该指令后,结果仍为0,且CF =0,否则CF = 1。
5、比较指令CMP OPRD1,OPRD2 功能: 将目的操作数减去源操作数,但不送结果,仅将结果反映在标志位上, 接着可用条件转移指令决定程序的流向。 以上5条指令实际上都做减法操作,而且都可以进行字或字节运算。对于双操作数指令,源操作数可以是寄存器、存储器或立即数;目的操作数可以是寄存器或存储器,但不能立即数,而且两个操作数不能同时为储存器。 对于单操作数指令,目的操作数可以是寄存器或存储器,但不能立即数, 如果操作数是存储器,还必须指出其类型。 例1:设(DX)= 3A49H,CF =1执行指令SBB DX,1850H执行结果 (DX)= 21F8H,CF=0 例2:已知(AL)= 13H执行指令NEG AL执行结果 (AL)= 0EDH
比较指令的应用 比较指令主要用在希望比较两个数之间的关系,而又不破坏原操作数的场合。即两者是否相等,或两个中哪一个大。一般有下列几种情况: * 在比较指令之后,根据ZF标志即可判断两者是否相等。若两者相等,执行CMP指令后,ZF=1,否则为0。 * 若是两个无符号数进行比较,则在比较指令之后,可根据CF的状态判断大小。 * 若是判断两个带符号数的大小,可根据 SF和OF进行判断。 在执行CMP AX,BX后 1、当无溢出(OF=0),若SF=0,则AX > BX;否则AX<BX。 2、当产生溢出(OF =1),若SF =0,则AX<BX;否则AX>BX。 即:OF “异或” SF =0,则AX>BX; OF “异或” SF =1,则AX<BX。
6、AAS未组合BCD码减法调整指令 功能:在用SUB或SBB指令对两个未组合十进制数进行相减后,对AL中所得结果进行调整,在AL中得到一个正确的未组合十进制数之差。如果有借位,则CF置 1。 影响AF、CF, 对OF、PF、SF、ZF 未定义。 7、DAS组合BCD码减法调整指令 功能:在两个组合十进制数用SUB或SBB相减后,结果已存放在AL中的情况下,用 DAS对AL进行调整,在AL中得到正确的组合十进制数。 影响AF、CF、PF、SF、ZF。对OF 未定义。
例:在BLOCK开始的内存单元中有100个16位带符号数,请寻找出最大值并送MAX单元。例:在BLOCK开始的内存单元中有100个16位带符号数,请寻找出最大值并送MAX单元。 MOV BX,OFFSET BLOCK;设置块指针 MOV AX,[BX] ;取一数送AX INC BX ;修改指针 INC BX MOV CX,99 ;设置比较次数 AGAIN: CMP AX,[BX] ;比较 JG NEXT ;AX>[BX]转NEXT MOV AX,[BX] ;小于,则小数送AX NEXT: INC BX ;修改指针 INC BX DEC CX ;比较次数减一 JNZ AGAIN ;未完,继续 MOV MAX,AX ;完,则存大数 HLT
(三)乘法指令 功能:完成将AL(字节)或AX(字)中的无符号数与源操作数相乘。 双倍长度的乘积送回到AX或DX:AX。 1、无符号数乘法指令MUL src 字节操作数:(AL) (src) AX 字操作数:(AX) (src) DX:AX 影响标志位CF、OF。若乘积的高半部分(在字节相乘时为AH,在字相乘时为DX)不为零,则标志CF=1,OF=1; 否则CF=0,OF=0。 例:设(AL)=90H,(BL)=04H。执行指令MUL BL后,(AX)=0240H,CF =1, OF =1 2、带符号数乘法指令IMUL src 功能:完成两个带符号数相乘, 操作及对标志位的影响与MUL指令完全类似。 功能:把在AX中的两个未组合十进制数相乘的结果,进行十进制数的调整,使得在AX中得到正确的未组合十进制数的乘积。 3、AAM 指令执行后影响标志位PF、SF、ZF,对AF、CF、OF 未定义。 例:设(AL)= 09H,(BH)=06H 执行MUL BL;(AL)= 36H AAM;调整得 (AH)= 05H,(AL)= 04H即 (AX)= 0504H 为未组合十进制数09和06相乘的结果54
(四)除法指令 1、无符号数除法指令 DIV src 功能:对两个无符号数进行除法运算。源操作数可以是字节或字。 字节操作数:(AX)/( src)(字节)的商 AL(最大为FFH),余数AH 字操作数:(DX:AX)/( src)(字)的商AX(最大为FFFFH),余数DX 若被除数只有16位,除数也是16位,则必须将16位被除数送AX,并将DX清0,然后相除。DIV指令执行后,所有标志位均无定义。 功能:该指令执行的操作与DIV相同,但操作数都必须是带符号数,商和余数也都是带符号数,而且规定余数的符号和被除数的相同,且所有标志位均无定义。 2、带符号数除法指令IDIV src 对于IDIV指令,字节操作时要求被除数为16位,字操作时要求被除数为32位。如果被除数不满足这个条件,不能简单地将高位置0,而应该先用下面的符号扩展指令将被除数转换成除法指令所要求的格式,再执行除法指令。 3、把字节转换为字指令CBW 功能:把AL中字节的符号位扩展到AH的所有位。 若(AL) <80H , 扩展后(AH) = 00H,若(AL) 80H,扩展后(AH) =0FFH。 该指令执行后,不影响标志位。
4、CWD 把字转换成双字指令 指令执行后,不影响标志位 功能:把AX中字的符号位扩展送到DX寄存器的所有位中去。 若(AX) < 8000H , 则(DX) = 0000H ; 若(AX) 8000H , 则(DX)= 0FFFFH 例:编程求-38/ 3的商和余数。 MOV AL,0BAH;被除数-38送ALMOV CH,03H;除数+3 送CHCBW;把字节扩展为字,使AX= 0FFBAHIDIV CH ;AL=0F4H=-12(商),AH=0FEH=-2(余数) 5、AAD未组合十进制数除法调整指令 功能:能把AX中的两个未组合的十进制数,在两个数相除以前进行校正。这样在两个未组合的十进制数相除以后,可以得到正确的未组合十进制结果。 例:设AX中存有两个未组合BCD数0307H,即十进制数37,BL中存有一个未组合十进制数05H,若要完成37/5的运算,可用以下两条指令:AAD ;(AH) 10 + (AL) = 37 = 25H ALDIV BL;(AL) = 7 (商),(AH) = 2 (余数) 注意:加法、减法和乘法的十进制调整指令都是紧跟在加法、减法和乘法运算指令之后,对运算结果进行调整。而除法的十进制调整指令AAD则不同,它是在除法运算之前进行调整。
三、逻辑运算指令 8088/ 8086可以对字节或字操作数按位操作,包括逻辑与、或、非、异或及测试和移位、循环移位指令。逻辑操作可以分成单操作数操作和双操作数操作两类。 (一)单操作数操作指令 1、NOT 逻辑非指令(取反指令) 指令格式:NOT src 功能:将目的操作数求反后送回目的操作数,即src src目的操作数可以是8位或16位寄存器或存储器。 指令执行后对标志位没有影响 例:设(BX)=8DCFH, 执行NOT BX后,(BX)=7230H
2、移位指令 SAL算术左移指令 0 SHL/ SAL 指令 CF MSB LSB SHL 逻辑左移指令指令格式:SHL OPRD,CNT 指令格式:SAL OPRD,CNT 功能:以上两条指令的功能完全相同,均将寄存器或存储器中目的操作数的各位左移,每移一次,最低有效位LSB补0,而最高有效位MSB进入标志位CF。移动一次,相当于将目的操作数乘以2。指令中的计数值CNT决定所要移位的次数。若只需要移位一次,可直接将指令中的CNT置1,若移位次数大于1,应先将移位次数送进CL寄存器,再把CL放在指令的CNT位置上。
SHR 逻辑右移指令 指令格式:SHR OPRD,CNT功能:对目的操作数中的各位进行右移,每执行一次移位操作,操作数右移一位,最低位进入CF,最高位补0。右移次数由计数值决定,同SAL/SHL指令一样。若目的操作数是无符号数,每右移一次,使目的操作数除以2,例如,右移2次相当于除以4,右移3次相当于除以8等等。但用这种方法作除法时,余数将被丢掉。 0 MSB LSB CF SHR 指令 SAR 算术右移指令 指令格式:SAR OPRD,CNT 功能:它的功能与 SHR 相似,移位次数由CNT决定。每移位一次,OPRD各位右移一位,最低位进入CF,但最高位(即符号位)保持不变,而不是补0。每移一次,相当于对带符号数进行除2操作。 SAR 指令 MSB LSB CF
指令执行后对标志位的影响: 标志位CF 总是为目的操作数最后被移出的那一位的值。 标志位OF:只有当CNT= 1时才有效,用以表示移位前后符号位是否改变,若改变,OF = 1 , 否则OF = 0。即对左移指令(SAL/ SHL),若移位后最高有效位与标志位CF 不相等,则OF = 1,否则OF = 0。而对右移指令,若移位后,操作数的最高有效位与次高位不同,则OF = 1,否则OF = 0。 标志位ZF、SF 根据指令执行后目的操作数的状态来决定,PF 只有当目的操作数在AL中时才有效。标志位AF 未定义。 例1:设(BL)= 5AH, 执行指令 SHL BL,1后 (BL)= 0B4H,标志位CF = 0,OF = 1 例2:设(DS)= 2800H,(DI)= 180AH,(2980AH)= 1256H 执行 MOV CL,02H SAR [ DI ],CL 后 (2980AH)= 0495H,CF = 1,ZF = 0,SF = 0
3、循环移位指令 ROL循环左移指令 指令格式:ROL OPRD,CNT ROR循环右移指令 指令格式:ROR OPRD,CNT RCL带进位循环左移指令 CF 指令格式:RCL OPRD,CNT RCR带进位循环右移指令 CF 指令格式:RCR OPRD,CNT 操作 CF MSB LSB CF MSB LSB 操作 操作 MSB LSB 操作 MSB LSB 四条指令都按指令中CNT规定的移位次数进行循环移位,移位后的结果仍送回目的操作数。OPRD可以是8/ 16位的寄存器或内存操作数,移位次数可以是1,也可以由CL寄存器的值指定。 标志位CF的值由最后一次被移出的值决定;OF位仅在CNT为1时才有效,在移位后操作数的最高有效位(符号位)发生变化时,则OF=1,否则OF置0. 例:设CF=1, (AL) =0B4H,若执行指令ROL AL, 1 ; 则(AL) = 69H, CF = 1, OF = 1 若执行指令RCR AL , 1 ; 则(AL) = 0DAH , CF =0, OF = 0
(二) 双操作数操作指令 该类指令能对两个操作数按位进行与、或、异或及测试操作。目的操作数可以是寄存器或内存操作数;源操作数可以是寄存器或内存操作数,还可以是立即数。 1、AND逻辑与指令 格式:AND OPRD1,OPRD2 2、TEST 测试指令 格式:TEST OPRD1,OPRD2 功能:对两个操作数进行按位“逻辑与”操作,结果送回目的操作数。主要用于使操作数的某些位保持不变(和‘1’相与), 而使某些位清0(和‘0’相与) 例: 设(AX) = 3538H , 执行指令 AND AX,0F0FH后 ; (AX) =0508H 功能:对两个操作数进行“逻辑与”操作, 但不回送结果, 即指令执行后两操作数不变。该指令常用在要检测某些条件是否满足,但又不希望改变原有操作数的情况下。紧跟在这条指令后面的往往是一条件转移指令,根据测试结果产生分支,转向不同的处理程序。 例如,要判断在BX寄存器中16位数的最高位是否为‘ 1’, 可用指令 TEST BX,8000H若最高位为‘ 1’,指令执行后,ZF = 0,若不是‘ 1’,则ZF = 1(结果是0)
3、OR “逻辑或”指令 格式:OR OPRD1,OPRD2 4、XOR 异或操作指令 格式:XOR OPRD1,OPRD2 功能:对两个操作数进行按位“逻辑或”操作,结果送回目的操作数。该指令主要用于使操作数的某些位保留(和‘ 0’相或),而使某些位置1 (和‘ 1’相或)。 例如,AX中存放两个未组合BCD数0509H,要将它们分别转换成ASCII码,结果仍放在AX中,则可用如下指令实现: OR AX,3030H;(AX) = 3539H 功能:对两个操作数进行按位逻辑异或运算,结果送回目的操作数。 主要用于使操作数的某些位保留(和‘ 0’相异或),而使某些位取反(和‘ 1’相异或)。 例如:欲使BH寄存器中的高4位取反, 低4位保持不变,可执行指令 XOR BH,0F0H
四、串操作指令 * 串操作指令是用于处理存放在存储器中的字或字节数据,字符串长度可达64K字节。 *串操作指令共有五种基本指令,可以对字符串进行传送、比较、搜索及存和取操作。 *在串操作指令可前加重复前缀,指令就重复执行,直至CX寄存器中的操作次数满足为止,重复过程可以被中断。 *串操作指令的源串位于当前数据段中,以SI为指针,目的串必须位于当前附加段中,以DI为指针。每执行一次串操作指令,指针SI和DI会自动修改,标志位DF=0为递增方向,这时在每次操作后SI、DI增量,字节操作时加1,字操作时加2;DF =1为递减方向,这时在每次操作后SI、DI减量,字节操作时减1,字操作时减2。要处理的字符串长度(字节或字数)放在CX寄存器中。
1、MOVS串传送指令 (不影响标志位) 格式:1) MOVS OPRD1,OPRD2 2) MOVSB(字节传送指令)MOVSW(字传送指令) 功能:把由SI作指针的源串中的一个字节或一个字,传送到由DI作指针的目的串中,且自动修改指针SI和DI。可方便地实现在存储单元之间传送数据。若在指令前加前缀 REP 则可执行至CX = 0 。 程序段:LEA SI,SRC LEA DI,LOC MOV CX,100 CLD REP MOVSB 例:编写程序段把数据段中以SRC为偏移地址,长度为100个字节的字符串,传送到附加段中以LOC为偏移地址的存储区域中。 AGAIN:MOVS LOC,SRC DEC CX JNZ AGAIN 指令REP MOVSB也可用几条指令代替
2、CMPS 串比较指令 格式:1) CMPS OPRD1,OPRD2 2) CMPSB (字节操作) / CMPSW (字操作) 功能:将以SI为指针的源串中的一个字(或字节)与DI为指针的目的串中的一个字(或字节)相比较(相减),但不影响操作数,结果反映在标志位上,同时相应修改源串和目的串的指针,指向串中的下一个元素。 标志位AF、CF、OF、PF、ZF和SF反映两个串的相应元素之间的关系。 在CMPS指令前可以加重复前缀,即REPE CMPS或REPZ CMPS;其功能相同,若比较结果为CX≠0(指定的长度还未比较完)和ZF=1(两串相等),则重复比较,直至CX=0(比完了)或ZF=0(两串不相等)时才停止操作。也可改用重复前缀REPNE或REPNZ,它们表示:若CX≠0(串没有结束)和串不等(ZF=0)则重复比较,直至CX =0或ZF=1时才停止比较。
初始化 (KA)和(KB)相应字符比较 N 串相等否? Y FF送GG 0送GG 暂停 程序段: 例:在自KA和KB单元开始各有一个由30个字符组成的字符串,检查这两个字符串是否相等,并在GG单元中建立一个标志(相等为00,不等为FFH) LEA SI,KA LEA DI,KB MOV CX,30 CLD REPE CMPSB JNZ L1 MOV GG,0 JMP L2 L1: MOV GG,0FFH L2: HLT 思考:第一个不相等的字符的地址 初始化:KA指针送SI KB指针送DI 串长送CX 指针增量变化
3、SCAS 串搜索指令 格式:1) SCAS 目的串2) SCASB 或 SCASW 功能: * 将AL(字节操作)或AX(字操作)的内容减去附加段中以DI为指针的目的串元素,结果反映在标志位上,但不改变目的串元素及累加器的内容。 * 操作后自动修改指针DI,使之指向下一个待搜索的串元素。 利用SCAS指令,可在内存中搜索所需要的数据(关键字)。指令执行前应先将关键字存放在累加器中。 SCAS指令前也可加重复前缀 REPE / REPZ,表示相等继续搜索,不等提前退出; REPNE / REPNZ表示不等继续搜索,相等提前退出。