1.指令中的操作数
计算机指令是由 操作码和 操作数两部分组成,操作码用来指出指令要完成的功能,操作数则给出了指令操作处理的对象。
指令中操作数类型划分如下:
源操作数:为指令的执行提供操作数,指令执行后其值保持不变。
目的操作数:为指令的执行提供操作数,指令执行后还要存放其结果,因此,目的操作数的原值不被保留。
零操作数:指令中不需要操作数,或者是操作数隐藏了。通常是一些处理器控制指令。
单操作数:指令只需要一个操作数,通常它既是源操作数,也是目的操作数。
双操作数:指令中含有两个操作数,一个是源操作数,另一个是目的操作数。两种操作数的寻址方式可以不同。
立即操作数:该操作数作为指令代码的一部分出现在指令中。在指令中只能做源操作数。立即操作数可以写成二进制(B)、十进制(D)、十六进制(H)。
寄存器操作数:寄存器操作数是把操作数存放在寄存器中,既可以做源操作数,也可以做目的操作数。
存储器操作数:存储器操作数是把操作数存放在内存中的某个单元中。在汇编指令中,以某种方式给出存储单元的地址。在程序中使用的是存储单元的逻辑地址。逻辑地址是由段基址和偏移量组成。段基址一般是隐含给出的,也可以用段前缀形式给出。偏移量也称为有效地址,用EA表示。
IO端口操作数:这是指操作数存放在输入输出端口的寄存器中。根据寻址方式的不同,在汇编指令中以不同的形式给出端口地址。
2寻址方式
8086的寻址方式如下:
立即数寻址方式、寄存器寻址方式、存储器寻址方式。
其中,存储器寻址方式还包括:
直接寻址方式
寄存器间接寻址方式
寄存器相对寻址方式
基址变址寻址方式
相对基址变址寻址方式
串操作寻址
端口寻址
//////////////////////////////////////////////////////////////////////////////////////
立即数寻址方式:立即数寻址的操作数是一个立即数,它直接包含在代码中,紧跟在操作码之后,与操作码一起存放在代码段中。立即数操作数只能作为源操作数,因此当一条指令的源操作数是立即数,目的操作数就必须是寄存器或者存储器操作数了。
其汇编指令格式如:
MOV AX, 2000H
MOV [BX], 10
立即数寻址主要用于给寄存器或存储单元赋初值,它可是是一个运算数,也可以是一个地址值。
寄存器寻址方式:指令中所需要的操作数在CPU的某个寄存器中。这类操作数的存取完全在CPU内部进行,不需要执行总线周期,所以执行速度快。寄存器寻址在汇编指令中直接写出了存放操作数的寄存器名。
其汇编指令格式如下:
MOV AX, BX
MOV CL, BL
存储器寻址方式:指令中的操作数都在存储器中,它又有多种寻址方式,寻址方式不同,有效地址(EA)的表达方法也不同。存储器寻址就是根据不同的寻址方式确定操作数的有效地址及隐含的段基址,从而形成物理地址,来对存储单元进行读写操作。
直接寻址方式:直接寻址方式的有效地址在指令中直接给出,默认的段基址是DS段寄存器。用中括号包含有效地址,表达存储单元的内容。
有效地址=16位位移量
汇编语言格式如下:
MOV AX, [2010H] ;AX <--- DS:[2010H] // DS:[2010H] = DS<<4 + 2010H
MOV [1010H], AL ;DS:[1010H] <--- AL
MOV BX, ES:[3020H] ;BX <--- ES:[3020H]
寄存器间接寻址方式:操作数的有效地址都在CPU的寄存器中,由于有效地址是16位,因此这种寻址方式必须使用16位的寄存器。8086规定用于间接寻址的寄存器为SI,DI,BX,BP。在用SI,DI,BX间接寻址时,隐含的基地址在DS,用BP间接寻址时,隐含的基地址在SS。可以用加段前缀的方法改变这种隐含关系。
这种寻址方式实际上是把偏移量事先存放在间接寻址的寄存器中。在程序中通过修改寄存器的内容,可以达到访问不同单元的目的。
有效地址=BX/BP/SI/DI的内容
汇编语言格式如下:
MOV AX, [BX] ;源操作数的物理地址=DS<<4+BX
MOV [BP], BL ;目的操作数的物理地址=SS<<4+BP
MOV CL, SS:[SI] ;源操作数的物理地址=SS<<4+SI
寄存器相对寻址方式:操作数的有效地址是由指令中指定的一个寄存器的内容和指令中给定的一个8位或者16位的位移量(e)相加后得到。
寄存器相对寻址方式有如下表示格式:
e[BX/BP/SI/DI ], [BX/BP/SI/DI ]e, [BX/BP/SI/DI+e ]
汇编语言格式如下:
MOV AX, 5[BX]
MOV BL, VAL[SI]
MOV 10H[BP], 10H
MOV DS:2[BP], AL ;DS<<4+BP+2
基址变址寻址方式:操作数的有效地址是由指令指定的一个基址寄存器(BX/BP)的内容加上一个变址寄存器(SI/DI)的内容。
有效地址=BX/BP + SI/DI
基址变址寻址方式格式如下:
[BX/BP ][SI/DI ], [BX/BP + SI/DI ]
注意:在一条指令中,基址寄存器(BX/BP)只能出现一个,变址寄存器(SI/DI)也只能出现一个。段基址的隐含指定只与基址寄存器有关。当选用BX时,段基址是DS,当选用BP时,段基址是SS。
汇编指令格式如下:
MOV AX, [BX][DI]
MOV AL, [BP][SI]
相对基址变址寻址方式和寄存器相对寻址方式类似:
有效地址=BX/BP + SI/DI+ 8/16位位移量
串操作寻址:串操作寻址专门用于串操作指令。串指的是一个字符串或一组数据,存放在连续的内存单元中。对串地址连续的数据操作时,用专门的串操作指令。寻址时隐含的使用变址寄存器SI,DI。
用SI做源串的地址指针,存放源数据串地址的偏移量,段基地址隐含在DS。
用DI做源串的地址指针,存放源数据串地址的偏移量,段基地址隐含在ES。
串操作指令在执行过程中能自动修改变址寄存器SI和DI的内容,使之成为数据串中下一个数据的地址。修改地址时是按照增量还是减量修改取决于标志寄存器中的方向标志位DF。DF=0时增量修改,DF=1时减量修改。
由于串是采用的隐含寻址方式,因此在串操作指令中只有操作码的助记符,无操作数。如串操作指令:MOVSB
指令中没有操作数,但实际是是对DS:[SI]为地址的源操作数和ES:[DI]为地址的目的操作数进行操作。
MOVSB:字符串传送指令,这条指令按字节传送数据。通过SI和DI这两个寄存器控制字符串的源地址和目标地址,比如DS:SI这段地址的N个字节复制到ES:DI指向的地址,复制后DS:SI的内容保持不变。
端口寻址:这是CPU对外设端口的一种寻址方式,这种寻址方式只用于输入输出指令。CPU与外部设备的连接要通过输入输出接口。CPU可以从输入设备接受信息,也可以向输出设备发送信息。外部设备与接口中的端口直接相连,当CPU要与外设交换信息或对外设进行某种控制时,是通过访问端口完成的。端口寻址就是在输入输出操作时如何确定端口地址。
8086有两种端口寻址方式:
(1) 直接端口地址:这种寻址方式是在指令中以8位立即数的形式直接给出端口地址,寻址范围是0~255。
在汇编指令中表示格式为:
输入指令:
IN AL, 24H ;将24H端口的内容送AL
IN AX, 20H ;将20H端口的内容送AX
输出指令:
OUT 21H, AL ;将AL的内容输出到21H的端口
OUT 23H, AX ;将AX的内容输出到23H的端口
注意:1) 输入输出指令中端口的直接地址不用括号;
2) 8086只能用累加器AL/AX与端口交换信息;
3) 端口宽度可为8位或16位,8位时与AL交换信息,16位时与AX交换信息。
(2) 间接端口寻址:间接端口寻址是将端口的地址事先送入寄存器DX,在输入输出指令端口地址由DX给出。由于DX是16位寄存器,因此间接端口寻址的范围是0~65535。
在汇编中表示格式如下:
输入指令:
IN AL, DX
IN AX, DX
输出指令:
OUT DX, AL
OUT DX, AX
8086提供了比较丰富的寻址方式,在编程时,选择合适寻址方式,会增加程序设计的灵活性,提高程序质量和编程效率。