710 likes | 834 Views
第三章 8086 的寻址方式和指令系统. 第一节 寻址方式. 二、寄存器寻址. 一、立即寻址. 三、直接寻址. 四、寄存器间接寻址. 六、基址加变址寻址. 五、 寄存器 相对 寻址. 七、相对基址加变址寻址. 第二节 指令系统. 二、算术运算指令. 一、数据传送指令. 四、串操作指令. 三、逻辑运算和移位指令. 六、处理器控制指令. 五、控制转移指令. 习题: 3-3(1 , 4 , 8 , 10) , 3-6( 单 ) , 3-9, 3-10 ( 1 , 4 ), 3-12 , 3-14( 单 ).
E N D
第三章 8086的寻址方式和指令系统 第一节 寻址方式 二、寄存器寻址 一、立即寻址 三、直接寻址 四、寄存器间接寻址 六、基址加变址寻址 五、寄存器相对寻址 七、相对基址加变址寻址 第二节 指令系统 二、算术运算指令 一、数据传送指令 四、串操作指令 三、逻辑运算和移位指令 六、处理器控制指令 五、控制转移指令 习题:3-3(1,4,8,10),3-6(单),3-9, 3-10(1,4),3-12,3-14(单)
第三章 8086的寻址方式和指令系统 3-1 8086的寻址方式 计算机的指令一般由操作码和操作数组成,操作码指出了指令的功能;而操作数则给出了指令操作的对象。操作数可以以立即数的形式存放在指令中,但在大多数情况下,操作数是以地址的形式存放在指令(指示操作数在哪儿)。用于说明操作数所在地址的方法称为寻址方式。 在微机中,操作数存放在: 1、在指令中;2、在CPU的某一内部寄存器中;3、在内存的数据区中;4、I/O端口。 在8086CPU中,内存地址是由数据段地址和段内偏移地址组成。而指令中给出的地址即为段内偏移地址——有效地址EA,有效地址EA构成的方法不同,则为不同的寻址方式。
M AH AL AX 操作码 码段 imL imH AX DS 一、立即寻址方式(Immediate Addressing) 例:MOV AX,im MOV AL,26H 操作数(8位或16的常数)直接包含在指令中,紧跟在操作码后面,与操作码一起放在代码段区域中。操作数im既可是8位的,也可是16位的。 imH imL 二、寄存器寻址(Register Addressing) 操作数存放在指令给出的寄存器中 例:MOV DS,AX
操作码 码段 00 20 数据段 30000 32000 32001 50 30 AL AH 三、直接寻址方式(Direct Addressing) 操作数的有效地址EA是指令的一部分,它与操作码一起放在代码段区域中。 操作数的物理地址为数据段寄存器DS加上16位地址偏移量。 例:若(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 Addressing) 例:若(DS)=2000H,(SI)=1000H MOV AX,[SI] 操作数在存储单元中。操作数的有效地址EA在指令所指定的寄存器中。可作为间址的寄存器有SI、DI、BX和BP 若: 1、指令中指定的寄存器为BX、SI或DI,则默认操作数存放在数据段中,段地址由DS提供 2、以寄存器BP间接寻址,则默认操作数存放在堆栈段中,段地址由SS提供 50 A0
操作码 操作码 码段 00 30 数据段 30000 35000 35001 50 30 AX 五、寄存器相对寻址方式(Register Relative Addressing) 操作数在存储单元中。操作数的有效地址是以指令指定的寄存器内容加上指令中给定的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 30 50
六、基址变址寻址方式(Based Indexed Addressing) 操作数在存储单元中。操作数的有效地址是一个基址寄存器(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 Addressing) 操作数在存储单元中。操作数的有效地址是基址寄存器(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、指令中使用方括号的地址表达式必须遵循下列规则: * 立即数可以出现在方括号内,表示直接地址; * 只有BX、BP、 SI 和 DI可以出现在方括号内,它们可以单独出现,也可以相加后出现,或以寄存器和常数相加的形式出现,但BX和BP不能同时出现在同一个[ ]内,SI和DI也不能同时出现; * 方括号有相加的含义,下面几种写法都是等价的: 1200[BX][SI] [BX+1200][SI] [BX+ SI +1200] * 方括号内包含BP,则隐含使用SS提供基地址;其余情况均隐含使用DS提供基地址。
2、段超越: 在8086系统中,数据通常在数据段中,但若需要,数据也可存放在代码段,堆栈段以及附加段中,这种情况就是段超越。应用时,需在指令中加以说明。 例:MOV AX,ES:[0500H] ES表示数据在附加段中; : 是修改属性运算符。
3、其它寻址方式 (1)隐含寻址:指令中不指明操作数 (2)I/O端口寻址:8086有直接端口寻址和间接端口寻址两种方式,端口寻址范围分别为0~FFH和0~FFFFH。 在直接端口寻址中,端口地址由指令直接提供,是一个8位立即数; 在间接端口寻址中,被寻址的端口号由寄存器DX提供。 (3)转移类指令寻址 (4)一条指令有几种寻址方式
数据传送 算术运算 逻辑运算和移位 串操作 一、数据传送指令 控制转移 处理器控制 (一)通用传送指令 立即数 通用指针变址寄存器 存储器 段寄存器CS、DS、ES、SS 3-2 8086的指令系统 按照功能,8086的指令可以分为六大类: MOV指令允许传送数据的途径如下图所示 1、 MOV 目的,源 功能:将源操作数的一个字节(B)或一个字(W)传送到目的操作数。 说明:* 指令中至少要有一项明确指出传送的是字节还是字; * 可用不同的寻址方式; * 不影响标志位; * 源操作数不变; *存储器之间,立即数至段寄存器,两个段寄存器之间不能用一条指令完成数据传送。
2、堆栈操作指令 操作:PUSH 操作时,先修改SP 的值,使 SP 2 SP 后,把源操作数(字)压入堆栈中 SP 指示的堆栈单元。源操作数可以是16位的通用寄存器,段寄存器,存储器中的字,但不能是立即数。 指令执行前 AX=2A8CH SP → 2000: 0130H 2000: 0000H 堆栈是以“ 先进后出”的方式工作的一个存储区, 进栈指令 PUSH 源 功能:将一个字的源操作数压入SP所指向的堆栈的顶部. 例:PUSH AX指令执行过程: 指令执行后 AX=2A8CH 2000: 0130H SP → 2AH 8CH 2000: 012EH SP → 2000: 0000H
出栈指令 POP 目的 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 目的,源 功能:把一个字或一个字节的源操作数与目的操作数交换。 交换可在寄存器之间、寄存器与存储器之间进行。 但段寄存器不能作为操作数,也不能直接交换两个存储单元中的内容。 例:设AX=31B0H,DS=3000H, BX=1800H,(31800H)= 1995H,执行指令 XCHG AX, [BX]的过程为: 执行指令后 执行指令前 AX 1995H 31B0H AX 19H 31H 31801H 31801H 95H B0H 31800H 31800H
4、表转换指令 XLAT 功能:将一个字节从一种代 码转换成另一种代码 指令格式: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、输入指令 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
(三)地址目标传送指令 这是一类专用于传送地址码的指令,可用来传送操作数的段地址和偏移地址,共包含以下三条指令: 1、LEA取有效地址指令 指令格式:LEA 目的 , 源 功能:把源操作数的地址偏移量,传送至目的操作数。 要求源操作数必须是存储单元;目的操作数必须是一个除段寄存器以外的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 目的,源 功能:从源操作数指定的存储单元中取出双字指针送到指令指定的寄存器(常指定SI)及DS寄存器中。 例:设DS=1200H,(13450H)=3F46H,(13452H)=0A92H 执行指令 LDS SI,[ 1450H ]后: SI = 3F46H, DS = 0A92H
3、LES将双字指针送到寄存器和ES指令 指令格式:LES 目的,源 功能:从源操作数指定的存储单元中取出双字指针送到指令指定的寄存器(常指定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 (入栈,修改,出栈)(8086无直接改变TF标志的指令)。
二、算术运算指令 (一)加法指令 1、ADD 目的,源 2、ADC 目的,源 功能:目的←源+目的+CF 8086指令系统提供了加、减、乘、除四种基本运算指令,可处理无符号或带符号的8位或16位二进制数的算术运算(带符号数是用补码表示)。还提供了各种调整操作指令,故可进行压缩的或非压缩的十进制数的算术运算。绝大部分算术运算指令都影响状态标志位。 功能:将源和目的操作数相加,结果送到目的操作数中,即 目的←源+目的 这两条指令的源操作数可以是寄存器、存储器或立即数,目的操作数只能用寄存器和存储单元。注意,源操作数和目的操作数不能同时为存储器,而且它们的类型必须一致,即都是字节或字。它们影响的标志位为: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,PF=1 3、INC 目的 增量指令(单操作数) 功能:对目的操作数加1,结果送回目的操作数。即目的←目的+1。目的操作数可以在通用寄存器或内存中。 指令执行后影响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←AL+06H ,AL = 96H 结果 AL = 96H, CF = 0, AF = 0
设置循环计数器 5送CX,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 目的,源 功能:目的←目的源 2、SBB 目的,源功能:目的←目的源CF 这两条指令均影响AF、CF、OF、PF、SF和ZF 3、DEC 目的减量指令功能:目的 ← 目的 1 执行后不影响CF,但影响 AF、OF、PF、SF和ZF 4、NEG 目的取负指令 功能:目的←0 目的 指令执行后影响AF、CF、OF、PF、SF和 ZF。若字节操作数为80H(128),字操作数为8000H(32768),执行NEG指令后操作数无变化,但OF =1。如操作数为0,执行该指令后,结果仍为0,且CF =0,否则CF = 1。
5、比较指令CMP 目的,源 功能: 将目的操作数减去源操作数,但不送结果,仅将结果反映在标志位上, 接着可用条件转移指令决定程序的流向。 以上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 =1,则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
(三)乘法指令 1、无符号数乘法指令MUL 源 功能:完成将AL(字节)或AX(字)中的无符号数与源操作数相乘。 双倍长度的乘积送回到AX或DX:AX。 字节操作数:AX ← AL 源字操作数: DX:AX ←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 源 功能:完成两个带符号数相乘, 操作及对标志位的影响与MUL指令完全类似。 功能:把在AL中的两个非压缩十进制数相乘的结果,进行十进制数的调整,使得在AX中得到正确的非压缩十进制数的乘积。 3、AAM 指令执行后影响标志位PF、SF、ZF,对AF、CF、OF 未定义。 例:设AL= 09H,BH=06H 执行MUL BH;AL= 36H AAM;调整得 AH= 05H,AL= 04H即 AX= 0504H 为非压缩十进制数09和06相乘的结果54
(四)除法指令 1、无符号数除法指令 DIV 源 功能:对两个无符号数进行除法运算。源操作数可以是字节或字。 字节操作数: AL← AX/源(字节)的商(最大为FFH),AH ←余数 字操作数: AX←(DX:AX)/源(字)的商(最大为FFFFH), DX ←余数 若被除数只有16位,除数也是16位,则必须将16位被除数送AX,并将DX清0,然后相除。DIV指令执行后,所有标志位均无定义。 功能:该指令执行的操作与DIV相同,但操作数都必须是带符号数,商和余数也都是带符号数,而且规定余数的符号和被除数的相同,且所有标志位均无定义。 2、带符号数除法指令IDIV 源 对于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 →AL,00→AHDIV BL;AL = 7 (商),AH = 2 (余数) 注意:加法、减法和乘法的十进制调整指令都是紧跟在加法、减法和乘法运算指令之后,对运算结果进行调整。而除法的十进制调整指令AAD则不同,它是在除法运算之前进行调整。
三、逻辑运算和移位指令 8088/ 8086可以对字节或字操作数按位操作,包括逻辑与、或、非、异或及测试和移位、循环移位指令。 (一)逻辑运算指令 1、NOT 逻辑非指令(取反指令) 指令格式:NOT 目的 功能:将目的操作数求反后送回目的操作数,即目的←目的 目的操作数可以是8位或16位寄存器或存储器。 指令执行后对标志位没有影响 例:设BX=8DCFH, 执行NOT BX后,BX=7230H
2、AND逻辑与指令 格式:AND 目的 ,源 3、TEST 测试指令 格式:TEST 目的,源 双操作数指令能对两个操作数按位进行与、或、异或及测试操作。目的操作数可以是寄存器或存储器;源操作数可以是寄存器或存储器,还可以是立即数。 功能:对两个操作数进行按位“逻辑与”操作,结果送回目的操作数。主要用于使操作数的某些位保持不变(和‘1’相与), 而使某些位清0(和‘0’相与) 例: 设AX = 3538H , 执行指令 AND AX,0F0FH后 ; AX =0508H 功能:对两个操作数进行“逻辑与”操作, 但不回送结果, 即指令执行后两操作数不变。该指令常用在要检测某些条件是否满足,但又不希望改变原有操作数的情况下。紧跟在这条指令后面的往往是一条件转移指令,根据测试结果产生分支,转向不同的处理程序。 例如,要判断在BX寄存器中16位数的最高位是否为‘ 1’, 可用指令 TEST BX,8000H若最高位为‘ 1’,指令执行后,ZF = 0,若不是‘ 1’,则ZF = 1(结果是0)
4、OR “逻辑或”指令 格式:OR 目的,源 5、XOR 异或操作指令 格式:XOR 目的,源 功能:对两个操作数进行按位“逻辑或”操作,结果送回目的操作数。该指令主要用于使操作数的某些位保留(和‘ 0’相或),而使某些位置1 (和‘ 1’相或)。 例如,AX中存放两个非压缩BCD数0509H,要将它们分别转换成ASCII码,结果仍放在AX中,则可用如下指令实现: OR AX,3030H;AX = 3539H 功能:对两个操作数进行按位“逻辑异或”运算,结果送回目的操作数。 主要用于使操作数的某些位保留(和‘ 0’相异或),而使某些位取反(和‘ 1’相异或)。 例如:欲使BH寄存器中的高4位取反, 低4位保持不变,可执行指令 XOR BH,0F0H
(二)算术逻辑移位指令 1、 SAL算术左移指令 0 SHL/ SAL 指令 CF MSB LSB 2、 SHL 逻辑左移指令指令格式:SHL 目的,计数值 指令格式:SAL 目的,计数值 功能:以上两条指令的功能完全相同,均将寄存器或存储器中目的操作数的各位左移,每移一次,最低有效位LSB补0,而最高有效位MSB进入标志位CF。移动一次,相当于将目的操作数乘以2。指令中的计数值决定所要移位的次数。若只需要移位一次,可直接将指令中的计数值置1,若移位次数大于1,应先将移位次数送进CL寄存器,再把CL放在指令的计数值位置上。
3、 SHR 逻辑右移指令 指令格式:SHR 目的,计数值 功能:对目的操作数中的各位进行右移,每执行一次移位操作,操作数右移一位,最低位进入CF,最高位补0。右移次数由计数值决定,同SAL/SHL指令一样。若目的操作数是无符号数,每右移一次,使目的操作数除以2,例如,右移2次相当于除以4,右移3次相当于除以8等等。但用这种方法作除法时,余数将被丢掉。 0 MSB LSB CF SHR 指令 4、 SAR 算术右移指令 指令格式:SAR 目的,计数值功能:它的功能与 SHR 相似,移位次数由计数值决定。每移位一次,目的操作数各位右移一位,最低位进入CF,但最高位(即符号位)保持不变,而不是补0。每移一次,相当于对带符号数进行除2操作。 SAR 指令 MSB LSB CF
指令执行后对标志位的影响: 标志位CF 总是为目的操作数最后被移出的那一位的值。 标志位OF:只有当计数值= 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
(三)循环移位指令 1、 ROL循环左移指令 指令格式:ROL 目的,计数值 操作 CF MSB LSB 2、 ROR循环右移指令 CF MSB LSB 操作 指令格式:ROR 目的,计数值 3、RCL带进位循环左移指令 操作 MSB LSB CF 指令格式:RCL 目的,计数值 4、RCR带进位循环右移指令 操作 CF MSB LSB 指令格式:RCR 目的,计数值 四条指令都按指令中计数值规定的移位次数进行循环移位,移位后的结果仍送回目的操作数。目的操作数可以是8/ 16位的寄存器或内存操作数,移位次数可以是1,也可以由CL寄存器的值指定。 标志位CF的值由最后一次被移出的值决定;OF位仅在计数值为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
四、字符串操作指令 * 字符串操作指令是用于处理存放在存储器中的字或字节数据,字符串长度可达64K字节。 *字符串操作指令共有五种基本指令,可以对字符串进行传送、比较、扫描及装入和存储操作。 *在字符串操作指令可前加重复前缀,指令就重复执行,直至CX寄存器中的操作次数满足为止,重复过程可以被中断。 *串操作指令的源串位于当前数据段中,以SI为指针,目的串必须位于当前附加段中,以DI为指针。每执行一次串操作指令,指针SI和DI会自动修改,标志位DF=0为递增方向,这时在每次操作后SI、DI增量,字节操作时加1,字操作时加2;DF =1为递减方向,这时在每次操作后SI、DI减量,字节操作时减1,字操作时减2。要处理的字符串长度(字节或字数)放在CX寄存器中。
1、MOVS串传送指令 (不影响标志位) 格式:1) MOVS 目的串,源串 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 目的串,源串 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表示不等继续搜索,相等提前退出。
块首址送DI 关键字送AL 块长送CX 增量调整指针 搜索关键字 N 搜索到否? Y 块指针减一 0送BX DI送BX 暂停 例:内存中以BUF0 单元开始的区域连续存放着一个长度为80的字符串(ASCII码串),查找字符串中是否有字符‘B’,若有,将关键字的地址送BX,若没有查到,则将BX寄存器清0。 程序段: LEA DI,BUF0 MOV AL,‘ B’ MOV CX,80 CLD REPNE SCASB JZ NEXT MOV BX,0 JMP DONE NEXT: DEC DI MOV BX,DI DONE: HLT
4、LODS 数据串装入指令(从串中取元素指令) 格式:1) LODS 源串2) LODSB或LODSW 功能:把数据段中以SI为指针的串元素,传送到AL( 字节操作) 或AX(字操作)中,同时修改SI,使它指向串中的下一个元素。 该指令一般不加重复前缀。 例:设 DS = 7000H, SI =0100H, (70100H) =08H, (70101H) =12H, DF=0, 执行指令LODSW后, AX =1208H, SI = 0102H .
5、STOS 数据串存储指令 格式:1) STOS 目的串2) STOSB 或STOSW 功能: 把累加器AL或AX中的一个字节或字, 传送到附加段中以DI为目标指针的目的串中, 同时修改指针DI, 以指向串中的下一个单元。 STOS指令可与REP重复前缀连用,即执行指令 REP STOS,能方便地用累加器中的一个常数,对一个数据串进行初始化。 例:设 (DS) =2000H , (ES) = 1000H , (DI) = 0500H , (AL) =20H , (CX) =10 , DF =0 执行指令REP STOSB后, 内存中10500H ~ 10509H 单元被置为20H ,同时使 (DI) = 050AH , (CX) =0。