1.07k likes | 1.3k Views
第 3 章 8086 的寻址方式和 指令系统. 【 本章重点 】 掌握指令系统的的基本格式,指令系统 的操作功能及使用方法。 【 本章难点 】 8086 的寻址方式,数据传送类指令 和算术运算类指令的使用。. §3.1 8086 的寻址方式. 3.1.1 操作数的寻址方式 1.立即数寻址 在这种寻址方式中,操作数直接跟在操作码的后面,参加指令所规定的操作,并且操作数与操作码一起放在代码段中。这种方式叫立即数寻址方式。. 例: MOV AX , 1234H
E N D
第3章 8086的寻址方式和 指令系统 【本章重点】掌握指令系统的的基本格式,指令系统 的操作功能及使用方法。 【本章难点】8086的寻址方式,数据传送类指令 和算术运算类指令的使用。
§3.1 8086的寻址方式 3.1.1操作数的寻址方式 1.立即数寻址 在这种寻址方式中,操作数直接跟在操作码的后面,参加指令所规定的操作,并且操作数与操作码一起放在代码段中。这种方式叫立即数寻址方式。 例:MOV AX,1234H 这条指令的功能是:把立即数1234H送入AX中。
图3-1 立即寻址示意图 2.寄存器寻址 如果操作数就在CPU的内部寄存器中,那么寄存器名在指令中给出。这种寻址方式就叫寄存器寻址方式。
例:MOV DS,AX 图3-2 寄存器寻址示意图 对16位操作数来说,寄存器可以为AX、BX,CX,DX、SI、DI、SP或者BP,对于8位操作数来说,寄存器可为AH,AL、BH,BL,CH,CL、DH,DL。 采用寄存器寻址方式的指令在执行时,操作就在CPU内部进行,不需要使用总线周期,因此,执行速度快。
3.直接寻址 使用直接寻址方式时,数据总是在存储器中,存储单元的有效地址由指令直接指出,所以直接寻址是对存储器进行访问时可采用的最简单的方式。 假如DS=3000H 例:MOV AX,DS:[2010H]
物理地址= DS×16+2010H=3000H×16+2010H=32010H 指令功能是将32010H和32011H两单元的内容送到AX中。 要注意的是采用直接寻址方式时,如果指令前面没有用前缀指明操作数在哪一段,则默认为段寄存器是数据段寄存器DS。 4.寄存器间接寻址 采用寄存器间接寻址方式时,操作数一定在存储器中,存储单元的有效地址由寄存器指出,这些寄存器可以为BX、BP,SI和DI之一,由于上述4个寄存器所黙认的段寄存器不同,这样又可以分两种情况:
①以SI、DI、BX进行间接寻址,则操作数通常存放在现行数据段中。此时数据段寄存器内容加上SI、DI、BX中的16位段内偏移地址,即得操作数的地址①以SI、DI、BX进行间接寻址,则操作数通常存放在现行数据段中。此时数据段寄存器内容加上SI、DI、BX中的16位段内偏移地址,即得操作数的地址 例:MOV AX,[SI] 和直接寻址的情况—样,如果指令前面没有用前缀指明具体的段寄存器,则寻址时默认的段寄存器通常为DS。如寄存器为BP时,则对应的段寄存器为SS。
②寄存器BP间接寻址,则操作数存放在堆栈段区域中。此时堆栈段寄存器内容加上BP中的16位段内偏移地址,即得操作数的地址。假如SS=3000H 例:MOV AX,[BP] 物理地址=SS×16+BP=30000H+2000H=32000H 指令功能是将32000H和32001H两单元的内容送到AX中。
5.寄存器相对寻址 在这种寻址方式中,操作数存放在存贮器中。操作数的地址是由段寄存器内容加上SI、DI、BX、BP之一的内容,再加上由指令所指出的8位或16位相对地址偏移量而得到的 例:MOV AX,DISP[SI] 物理地址=DS×16+SI+DISP=30000H+1000H+0300H=31300H指令功能是将31300H和31301H两单元的内容送到AX中。
6.基址、变址寻址 在8086中,通常把BX和BP作为基址寄存器,而把SI、DI作为变址寄存器。将这两种寄存器联合起来进行的寻址就称为基址、变址寻址。这时,操作数的地址应该是段寄存器内容×16加上基址寄存器内容(BX或BP内容),再加上变址寄存器内容(SI或DI内容)而得到的. 例:MOV AX,[BX][SI]
物理地址=DS×16+SI+BX=30000H+1000H+3000H=34000H 指令功能是将34000H和34001H两单元的内容送到AX中。 例:MOV AX,[BP][SI] 物理地址=SS×16+BP+SI=30000H+3000H+1000H=34000H 指令功能是将340000H和34001H两单元的内容送到AX中。
7.基址、变址相对寻址 这种寻址实际上是基址、变址寻址的扩充。即操作数的地址是由基址、变址方式得到的地址再加上由指令指明的8位或16位的相对偏移地址而得到的 例:MOV AX,DISP[BX][SI] 物理地址=DS×16+SI+BX+DISP=30000H+1000H+3000H+0300H=34300H 指令功能是将34300H和34301H两单元的内容送到AX中。
3.1.2 转移地址的寻址方式 1.段内直接寻址 段内直接寻址方式也称为相对寻址方式,转移的目标地址是当前IP内容和一个8位或16位的位移量DISP之和。即物理地址=CS×16+IP+DISP 例:JMP DISP 图3-10中,1000H是CPU读取这条指令的位移量50H后IP的内容。所以,该指令使CPU转向31050H去执行。
2.段内间接寻址 这种寻址方式在段内进行,其转移的目标地址是16位寄存器或两个相邻的存储单元的内容,即以寄存器或存储器单元内容来更新IP的内容。如图3-11所示。 例:JMP CX JMP WORD PTR[BX]
3.段间直接寻址 在这种寻址方式中,指令码中将直接给出16位的段地址和16位的段内偏移地址。 例:JMP FAR PTR DADD1
4.段间间接寻址 这种寻址方式和段内间接寻址相似。但是,由于确定转移地址需要32位信息,因此只适用于存贮器寻址方式。用这种寻址方式可计算出存放转移地址的存贮单元的首地址,与此相邻的4个单元中,前两个单元存放16位的段内偏移地址;而后两单元存放的是16位的段地址,如图3-13所示。 例:JMP DWORD PTR[BP][DI]
§3.2 8086指令系统 8086的指令系统大致可分为6种类型: ①数据传送指令 ②算术运算指令 ③逻辑运算和移位指令 ④串操作指令 ⑤程序控制指令 ⑥处理器控制指令
3.2.1数据传送指令 8086有5类传送指令,以实现CPU的内部寄存器之间、CPU和存储器之间、CPU和I/O端口之间的数据传送。 1.通用传送指令 通用传送指令中包括最基本的传送指令MOV,交换指令XCHG,椎栈指令PUSH和POP,字节、字转换指令CBW和CWD。 (1)最基本的传送指令 指令格式:MOV OPRDl,OPRD2 执行功能:该指令可把一个字节或一个字操作数从源地址传送到目的地址中去。 OPRD1:可以是累加器、寄存器、存贮器以及立即操作数 OPRD2:可以是累加器、寄存器和存贮器。
图3-14 数据传送方向示意图 1)在CPU各内部寄存器之间传送数据(除代码段寄存器CS和指令指针IP以外)。
MOV AL,BL ;BL中的8位数据送AL MOV DH,CL ;CL中的8位数据送DH MOV CX,AX ;将AX中的16位数据送CX MOV BX,DI ;将DI中的16位数据送BX MOV DS,AX ;将AX中的16位数据送DS MOV ES,AX ;将AX中的16位数据送ES
2)立即数传送至CPU的内部通用寄存器(即AX、BX、CX、DX、BP、SP、SI、DI),给这些寄存器赋值。2)立即数传送至CPU的内部通用寄存器(即AX、BX、CX、DX、BP、SP、SI、DI),给这些寄存器赋值。 MOV CL,4 ;立即数8送入CL中 MOV AX,03FFH ;将立即数数03FFH送入AX中 MOV CX,1000H ;将立即数1000H送入CX中 MOV BL,40 ;将立即数40送BL中 MOV SI,057BH ;将立即数057BH送入SI中
3)CPU内部寄存器(除了CS和IP以外)与存贮器(所有寻址方式)之间的数据传送,与前述一样可以传送一个字节也可以传送一个字。3)CPU内部寄存器(除了CS和IP以外)与存贮器(所有寻址方式)之间的数据传送,与前述一样可以传送一个字节也可以传送一个字。 MOV AL,BUFFER ;将BUFFER为首地址的一个单 元内容送AL MOV AX,[BX] ;BX和BX+1所指的两个内存单元的内容送AX MOV [DI],AX ;累加器的内容送DI和DI+1所指的两个单元 MOV AX,[SI+4] ;将SI+4和SI+4+1所指的两个单元内容送入AX 需要注意的是,MOV指令不能在两个存贮器单元之间进行数据直接传送。为了实现存贮器单元之间的数据传送,必须用内部寄存器作为中介。 MOV AL,DATAl MOV DATA2,AL
(2)交换指令 指令格式: XCHG OPRDl,OPRD2 执行功能:交换指令把一个字节或一个字的源操作数与目的操作数相交换。 XCHG AL,CL ;累加器低8位和通用寄存器CL之间交换 XCHG AX,DI ;累加器AX和通用寄存器DI之间交换 XCHG BX,SI ;通用寄存器BX和通用寄存器SI之间交换 XCHG AX,BUFFER ;累加器AX和BUFFER为首地址的两个单元交换 XCHG BX, [SI] ;通用寄存器BX和存储器SI和SI+1两个单元交换
(3)堆栈操作指令 PUSH OPRD(压入堆栈指令) POP OPRD(弹出堆栈指令) 例如: MOV AX,1234H MOV DX,5678H MOV SP,2000H PUSH AX PUSH DX ┇ POP DX POP AX
当执行完两条压入堆栈的指令时,堆栈中的内容如图3-15所示。当执行完两条压入堆栈的指令时,堆栈中的内容如图3-15所示。 ①SP-l → SP ;SP=1FFFH ,(SP)←AH ②SP-l → SP ;SP=1FFEH ,(SP)←AL ③SP-l → SP ;SP=1FFDH ,(SP)←DH ④SP-l → SP ;SP=1FFCH ,(SP)←DL
每执行一条压入堆栈指令,堆栈地址指针SP减2,压入堆栈的数据放在栈项。每执行一条压入堆栈指令,堆栈地址指针SP减2,压入堆栈的数据放在栈项。 弹出堆栈的过程与此刚好相反,每弹出1个字,栈顶指针SP的值加2。 ①DL←(SP) ;SP+l → SP ,SP=1FFDH ②DH←(SP) ;SP+l → SP ,SP=1FFEH ③AL←(SP) ;SP+l → SP ,SP=1FFF H ④AH←(SP) ;SP+l → SP ,SP=2000H
2.地址传送指令 8086有3条地址传送指令。 (1)LEA指令 指令格式: LEA OPRDl,OPRD2 执行功能:该指令把源操作数OPRD2的地址偏移量传送至目的操作数OPRDl中。 源操作数必须是一个内存操作数,目的操作数必须是一个16位的通用寄存器。这条指令通常用来建立串指令操作所需的地址指针。 LEA BX,DATA 和MOV BX,OFFSET DATA等价 LEA SI,BUFFER 和MOV SI,OFFSET BUFFER等价
(2)LDS指令 该指令完成一个地址指针的传送。地址指针包括段地址和地址偏移量。指令执行时,将段地址送入DS,地址偏移量送入一个16位的指针寄存器或变址寄存器。 例如: LDS SI,[BX] 是把BX所指的32位地址指针的段地址送入DS,偏移地址送入SI。 (3)LES指令 这条指令除将地址指针的段地址送入ES外,其他操作与LDS的类似。 例如: LES DI,[BX] 是把BX所指的32位地址指针的段地址送入ES,偏移地址送入DI。
3.输人输出指令 输入/输出指令用来完成累加器(AX/AL)与I/O端口之间的数据传送功能。 执行输入指令时,CPU可以从一个8位端口读入一个字节到AL中,也可以从两个连续的8位端口读一个字到AX中。 指令格式:IN 累加器,端口地址 执行输出指令时,CPU可以将AL中的一个字节写到一个8位端口中,或者将AX中的一个字写到两个连续的8位端口中。 指令格式:OUT 端口,累加器 端口地址的寻址范围是64K(0000H~FFFFH),若端口地址在00H~FFH之间,可以使用直接寻址方式,否则只能由16位寄存器DX来作间接寻址。
例如: IN AX,20H ;读20H、21H端口一个字的数据到AX中 OUT 22H,AL ;将AL中的数据从22H端口输出 MOV DX,210H ;端口 地址210H送DX IN AL,DX ;读210H端口一个字节到AL中 OUT DX,AX ;将AX中的数据从210H端口输出
3.2.2算术运算指令 8086可提供加、减、乘、除4种基本算术运算的操作指令。这些指令可实现字节或字 的运算,也可以用于符号数和无符号数的运算。 进行加、减运算的源操作数和目的操作数的关系
1.加法指令 (1)不带进位的加法指令 指令格式:ADD OPRDl,OPRD2 指令功能:OPRDl←(OPRDl)+(OPRD2) ADD指令两个操作数相加,结果送至目的操作数。 源操作数可以是累加器、通用寄存器、存贮器和立即数。 目的操作数可以是累加器、通用寄存器或存贮器。例如: ADD AL,30 ;AL←(AL)+30 ADD AX,1000H ;AX←(AX)+1000H ADD BX,3FFH ;BX←(BX)+3FFH ADD AX,SI ;AX←(AX)+(SI) ADD SI,AX ;SI←(SI)+(AX) ADD DI,CX ;DI←(DI)+(CX)
ADD AL,DATA[BX] ;AL←(AL)+((BX+DATA)) ADD DX,DATA[BX+SI] ;DX←(DX)+((BX+SI+DATA)) ADD BETA[SI],100 ;(SI+DETA)←((SI+BETA))+100 ADD BETA[SI],AX ;(SI+DETA)←((SI+BETA))+(AX) 注意,两个存储器操作不能直接相加,段寄存器也不能参加运算。在使用时还要注意两个操作数类型一致。 例如:ADD AX,0CFA8H 若指令执行前,(AX)=5623H,则指令执行后,(AX)=25CBH,且 CF=1,OF=0,SF=0,ZF=0,AF=0,PF=1。 这些指令执行时,对标志位CF、OF、SF、ZF和AF都会产生影响。
(2)带进位的加法指令 指令格式:ADC OPRD1,OPRD2 指令功能:OPRD1←(OPRD1)+(OPRD2)+CY 这条指令与ADD指令基本相同,只是在对两个操作数进行相加运算时还应加上进位位的当前值,然后再将结果送至目的操作数。 例如:现有两个双精度字00127546H和00109428H,其中被加数00127546H存放在DATA1为首的内存单元中,加数00109428H存放在DATA2为首的内存单元中。要求结果存放在DATA3为首的单元中。
MOV AX,DATA1 ADD AX,DATA2 MOV DATA3,AX MOV AX,DATA1+2 ADC AX,DATA2+2 MOV DATA3+2,AX 该指令对标志位的影响与ADD指令对标志位的影响相同。
(3)INC加1指令 指令格式:INC OPRD 指令功能:OPRD←(OPRD)+1 这条指令对指定的操作数进行加1操作,在循环程序中常用于修改地址指针和循环次数等。其操作数可以是通用寄存器,也可以是存储器。 该指令执行结果对标志位AF、OF、PF、SF和ZF有影响,而对CF位不产生影响,例如: INC AL INC CX INC WORD PTR[SI] INC BYTE PTR [SI+BX]
2.减法指令 (1)不带借位的减法指令 指令格式:SUB OPRDl,OPRD2 指令功能:OPRD1←(OPRD1)-(OPRD2) 该指令用来对目的操作数和源操作数的字或字节进行相减,其结果存放在目的操作数。 源操作数OPRD2:可以是累加器、通用寄存器、存储器、立即数。 目的操作数OPRD1:可以是累加器、通用寄存器、存储器。 SUB AL,78H ;AL←(AL)-78H SUB BX,5678H ;BX←(BX)-5678H SUB AX,CX ;AX←(AX)-(CX)
SUB AL,4[SI] ;AL←(AL)-((SI+4)) SUB DX,1000H[BX+SI] ;DX←(DX)-((BX+SI+1000H)) SUB [SI+5],100 ;(SI+5)←((SI+5))-100 SUB [SI+2000H],AX ;(SI+2000H)←((SI+2000H))-(AX) 指令执行后对各状态标志位OF、SF、AF、PF和CF均可产生影响。 (2)带借位的减法指令 指令格式:SBB OPRD1,OPRD2 指令功能:OPRD1←(OPRD1)-(OPRD2)-CY 该指令与SUB相类似,只不过在两个操作数相减时,还应减去借位标志CF的当前值。这条指令主要用于多字节的减法运算。 该指令对标志位AF、CF、OF、PF、SF和ZF都将产生影响。
(3)DEC减1指令 指令格式:DEC OPRD 指令功能:OPRD←(OPRD)-1 该指令实现对操作数的减1操作,所用的操作数可以是寄存器的,也可以是存储器。 在相减时,把操作数看作为无符号的二进制数。该指令执行结果将影响标志位AF、OF、PF、SF和ZF,但对CF标志不产生影响,例如: DEC BL DEC CX DEC BYTE PTR[SI]
(4)NEG求补指令 指令格式:NEG OPRD 指令功能:OPRD←0-(OPRD) 该指令用来对操作数进行求补操作,即用零减去操作数,然后再将结果送回。相当于操作数求反加1并保存在目的操作数中。 例如: NEG AL NEG BYTE PTR[SI] 如果操作数的值为-128(16进制数为80H)或者一32 768(16进制数为8000H),,执行求补指令后,操作数没有变化,但溢出标志OF=1。
(5)比较指令 指令格式:CMP OPRDl,OPRD2 指令功能:(OPRD1)-(OPRD2) 该指令执行减法操作,不保存相减的结果。指令执行后两操作数的内容不变,但相减的结果影响标志位。在程序设计时,比较指令通常为程序的转移提供条件。 例如:CMP AX,2000H CMP AL,50H CMP DX,SI CMP AX,[BX+SI+10H] 比较指令在执行时,会影响标志位AF、CF、OF、PF、SF、ZF。
如何利用状态标志来判断两操作数的关系呢?下面分三种情况来分析。如何利用状态标志来判断两操作数的关系呢?下面分三种情况来分析。 1)两个操作数相等 如果所比较的两个操作数相等时,那么标志位ZF=1,所以根据ZF就可以判断两数是否相等。 2)两个操作数不等 两个无符号数的比较 无符号数相减时,CF就是借位标志。如果CF=0,表示无借位,即被减数大,减数小。如果CF=1,表示有借位,即被减数小,减数大。 两个有符号数的比较 两个有符号的比较时,同符号数相比较,相减的结果不会超出带符号数的表示范围,即不会产生溢出,OF=0;两个不同号的带符号数比较,相减的结果有可能产生溢出。这时可以用如下结论判断。 当OF⊕SF=0时,OPRD1>OPRD2。 当OF⊕SF=1时,OPRD1<OPRD2。
CMP AL,0 ;AL和0进行比较 JGE NEXT ;若AL≥0则转到NEXT执行 例如,若自BLOCK开始的内存缓冲区中,有100个带符号的数,希望找到其中最大的一个值,并将它放到MAX单元中。 MOV SI,OFFSET BLOCK MOV AL,[SI] INC SI MOV CX,99 AGAIN: CMP AL,[SI] JG NEXT MOV AL,[SI] NEXT: INC SI DEC CX JNE AGAIN MOV MAX,AL HLT
3.乘法指令 8086的乘法指令分为无符号数乘法指令和带符号数乘法指令两种。 (1)无符号数乘法指令MUL 指令格式:MUL OPRD 指令功能:若OPRD为字节数据,则执行AX←(AL)×(OPRD) 若OPRD为字数据,则执行DX、AX←(AX)×(OPRD) 目的操作数为:AL或AX(隐含给出) 源操作数为:通用寄存器、存储器。不能为立即数和段寄存器。 MUL指令对状态标志CF、OF有影响,SF、ZF、AF、PF不确定。
例如: MUL AL MUL BX MUL WORD PRT[SI] 要完成14×15可以用下列指令: MOV AL,14 MOV CL,15 MUL CL (2)带符号数乘法指令IMUL 指令格式:IMUL OPRD 指令功能:若OPRD为字节数据,则执行AX←(AL)×(OPRD) 若OPRD为字数据,则执行DX、AX←(AX)×(OPRD) 目的操作数为:AL或AX(隐含给出)
4.除法指令 8086有两条除法指令:无符号除法指令和带符号除法指令。它们都可以进行字节或字除法运算,并且规定,8位除法的被除数在AX中;16位除法的被除数在DX与AX中,除数均由指令指出。对8位数除法,商与余数分别放在AL与AH中,对16位除法,商与余数分别放在AX与DX中。 (1)无符号数除法指令DIV 指令格式:DIV OPRD 指令功能:OPRD为字节数据:AL←(AX)÷(OPRD) 商 AH←(AX)÷(OPRD) 余数 OPRD为字数据:AX←(DX) (AX)÷(OPRD) 商 DX←(DX) (AX)÷(OPRD) 余数
(2)IDIV带符号数除法指令 指令格式:IDIV OPRD 指令操作:与DIV指令相同,但被除数、除数、商、余数全部均为带符号数,且余数的符号位同被除数。即IDIV执行后,CF、OF、AF、PF、ZF、SF不确定。 用IDIV指令时,如果是一个双字除以一个字,则商的范围为-32768~32767;如果是一个字除以一个字节,则商的范围为-128~127。运算结果超出了表示范围,那么会作为除数为0的情况来处理,即产生0号中断。
例如:在存储器中有X和Y两个单元,存有无符号数,现要求完成X/Y,将商存入Z单元。执行的指令如下:例如:在存储器中有X和Y两个单元,存有无符号数,现要求完成X/Y,将商存入Z单元。执行的指令如下: MOV AL,X MOV AH,0 DIV Y MOV Z,AL