8086寻址方式可分为两类:数据寻址方式和转移地址寻址方式
数据寻址方式就是通过地址查找数据(操作数),告诉CPU存取数据的地方。
数据寻址方式通常分为四类:立即数寻址;寄存器寻址;存储器寻址;隐含寻址。
其中存储器寻址又可以分为五类:直接寻址;寄存器间接寻址;寄存器相对寻址;基址变址寻址;基址变址且相对寻址。
数据寻址方式
下面依次介绍每种寻址方式:
1.立即数寻址
当数据为8位或16为时,可直接放在指令本身最后一个字节或两个字节中。这样的数据成为立即操作数。操作数直接从指令代码中立即得到,即立即数,用常量的形式直接表达。
立即数寻址方式只用于源操作数,常用来给寄存器和存储单元赋值。
举例:
MOV AX,0102H;机器代码:B8 02 01 操作码:B8 立即数:0102
2.寄存器寻址
数据存放在指令规定的寄存器中,对于16位数据,寄存器可以是 AX BX CX DX SI DI SP BP;对于8位数据可以是数据寄存器的高8位或者低8位即AL AH BL BH CL CH DL DH
举例:
MOV AX,BX
3.存储器寻址
操作数在存储单元中,编程时需要用到逻辑地址即:段地址和偏移地址。段地址可以使用默认逻辑段,不用显式说明;一般BX SI DI默认的逻辑段是DS(数据段)BP SP默认的逻辑段为SS(堆栈段);段地址必要时要使用段地址前缀显式说明例如:SS:[BX]
存储器寻址可以分为五类:直接寻址;寄存器间接寻址;寄存器相对寻址;基址变址寻址;基址变址且相对寻址。
3.1 直接寻址
操作数在存储单元中,其16位有效地址,即段内偏移地址在指令码之中,占两个字节
举例:
MOV AX, [1000H];默认是在数据段中 即相当于DS:[1000H]
在实际的汇编语言程序设计中,如果程序比较复杂,而用到的存放数据的单元又很多,那么在直接寻址方式当中,用户就要记住存放数据的每个单元的地址,同时还要记住该地址单元存放的数据的意义,这样对设计程序带来了很大的困难。所以在实际的汇编语言程序设计中,常常采用给存放数据的单元,定义一个符号地址名,即变量名/变量。
变量名一旦定义了,就具有五个属性:该单元的段地址,该单元的偏移地址,类型,大小,长度;这样,在程序设计中就可以用整个变量名代替原来存储单元的实际地址。
举例:
MOV AX, DATA1;主存操作数常通过变量形式引用,一般不需要使用段地址前缀
3.2 间接寻址
操作数在存储单元中,其有效地址在指令码指明的基址寄存器BX或变址寄存器SI DI之中。有效地址可表示为;其段地址默认是在DS段。
MOV AL,[BX] ;字节量传送,16位有效地址
MOV AX,[SI] ;字量传送,16位有效地址
MOV WORD PTR [BP],1234H ;字量传送,16位有效地址
3.3 相对寻址
操作数在存储单元中,其有效地址是一个8位或16位的位移量(用disp表示)与基址寄存器(包含基址指针)或变址寄存器的内容之和。位移量disp和这个寄存器在指令码中给出,有效地址可表示为
在disp为常数时,操作数所在单元的段地址以寄存器为准,若寄存器位BX SI DI,操作数默认在段中。若寄存器位BP,操作数默认在SS段中。
在disp为变量时,操作数所在单元的段地址以变量为准,变量在那个段定义就去该段的段地址。
MOV AX,[DI+06H] ;AX←DS:[DI+06H]
;寄存器:DI
;位移量:06H
;有效地址:EA=DI+06H
MOV AX,[BP-06h] ;AX←SS:[BP-06H]
;使用BP寄存器,默认配合SS段寄存器
这种寻址方式可用作表格处理:表格的首地址可设置为位移量,修改基地址或者变址寄存器的内容取得表格中的值。
3.4 基址变址寻址
操作数在存储单元中,其有效地址是一个基址寄存器和一个变址寄存器的内容之和。基址寄存器和变址寄存器在指令码中指明。其有效地址可表示为:
该单元的段地址以基址寄存器为准,若基址寄存器为BX,则段地址寄存器默认在DS中,若基址寄存器为BP,则段地址默认在SS中。
举例:
MOV AX, [BX][SI]
MOV AX, [BX+SI]
便于支持一维数组、表格等数据结构首地址可存放在基址寄存器中,而用变址寄存器来访问数组中的各个元素。由于两个寄存器的值都可以修改,所以它比寄存器相对寻址方式更加灵活。
3.5 基址变址且相对寻址
操作数在存储单元中,其有效地址是一个8为或16位的位移量disp、一个基地址寄存器内容和一个变址寄存器内容三部分之和,即为
举例:
;有效地址=基址寄存器+变址寄存器+位移量
MOV AX,[BX+SI+06H] ;AX←DS:[BX+SI+06H]
;允许两个寄存器都用中括号,位移量在中括号前
MOV AX,06H[BX+SI] ;AX←DS:[BX+SI+06H]
MOV AX,06H[BX][SI] ;AX←DS:[BX+SI+06H]
这种寻址方式便于支持二维数组的寻址:存储器存放着多个记录组成的文件,位移量指向文件之首,基址寄存器指向某个记录,变址寄存器指向该记录的第一个元素。
这种寻址方式为堆栈处理提供了方便:一般BP可指向栈顶,从栈顶到数组的首地址可用位移量来表示,变址寄存器可用来访问数组中的某个元素。
综上所述
位移量是存放指令中的一个8bit或者16bit的数,但它不是立即数,而是一个地址。
基址(Base)是存放在基址寄存器(BP BP)中的内容,通常用来指向数据段中数组或者字符串的首地址。
变址(Index)是存放在变址寄存器(SI DI)中的内容,它通常用来访问数组中的某个元素或字符串中的某个字符。
转移地址寻址方式
指令是按照顺序存放在存储器中的,其执行顺序是由代码段起存其CS和指令指针IP的内容决定。在正常的情况下,BIU自动修改IP的内容,使它指向下一条指令。程序转移指令通过改变IP和CS的内容,就可以改变程序的正常执行顺序。
转移地址的寻址方式指寻找操作数作地址用,给IP或给CS:IP,最终确定一条证零的地址,从而实现程序的转移。如果程序转移后只有IP发生了改变,则称为段内转移或进程转移(也称为NEAR转移);如果转移后CS IP均发生了变化,则成为段间转移或者称为远程转移(也称为FAR转移)
转移地址的寻址方式由4种:段内直接寻址,段内间接寻址,段间直接寻址,段间间接寻址
8086指令系统中转移指令有两大类:无条件转移指令(JMP,CALL,RET,IRET)条件转移指令(JZ,JCM,JCXZ,LOOP)
1.段内直接寻址
在段内直接寻址方式中,指令码包括一个位移量disp,转移的有效地址为(IP)+disp,因为位移量是相对于当前IP内容来计算的,所以有又称为相对寻址。disp可以是16位,也可以是8位。如果disp是8位,则称为段内短程转移。无论是8位还是16位,disp在指令码中都是用补码的表示有正负号的数。
JMP指令操作数部分直接给出目标单元,指令在存储单元的地址形成CS*10H+IP;IP=IP+disp
例如
转移的目的地址与当前指令在同一个段,通常用目的地址标号表示 JMP MAIN
2.段内间接寻址
在段内间接寻址方式中,在同一代码段内,要转移到的地址的16位段内偏移地址(即有效地址)在一个16位寄存器中或在存储器相邻的两个单元中。这个寄存器或相邻的两个单元的第一个单元的地址,是在指令码中以上面讨论的数据的寻址方式给出的。只不过寻址方式决定的地址里放的不是一般的操作数,而是转移地址。
转移的目的地址与当前指令在同一个段,通常用一个16位地址来表示目的地址。
JMP指令转移的目标地址在某一个通用寄存器或者在某一个字存储单元中
举例:
JMP CX
;或者
JMP WORD PTR [BX]
3.段间直接寻址
在段间直接寻址方式中,指令码中直接给出16位段地址和16位有效地址;目的地址和当前指令不在同一个段,通常用一个32位的地址表示目的地址。JMP FAR PTR MAIN1
4. 段间间接寻址
段间间接寻址与段内间接寻址方式相似,但不可能有寄存器间接寻址,因为要得到的转移地址位32位(16位段地址和16位有效地址)。指令中一定给出某种访问内存单元的寻址方式。用这种寻址方式计算出存储单元地址开始的连续的4个单元的内容就是要转移的地址,其中前两个但馆内的16位值为有效地址,后两个单元内的16位为段地址。
属于转移类指令的有转子程序指令CALL、无条件转移指令JMP和多种条件指令等。并不是每种指令都属于上述4中寻址方式。
段间间接寻址和段内间接寻址方式相似,要得到的转移地址包括16位段地址和16位有效地址,使用地址连续的4个存储单元存储。
指令所在存储单元的地址的形成:IP←EA存储单元的前两个字节;CS←段地址存储单元的后两个字节。
JMP DWORD PTR ADDR[BX]
;或者
MP DWORD PTR [BX][SI]