• 8086寻址方式


    数据寻址

      指令中,“数据寻址”指操作数(源操作数和目的操作数)的寻址方式,源操作数和目的操作数可以有不同的寻址方式。

    立即寻址

      所谓立即,就是取数不需要再去访问存储器和寄存器,而直接在指令中给出(此时指令已经从存储器中加载到了指令队列缓冲器)。大多是常量被赋值给寄存器的情况,目的操作数一般不会出现立即寻址:

    MOV AX, 12A2H;//源操作数立即寻址
    MOV AL, 01H;//源操作数立即寻址

    寄存器寻址

      数据放在寄存器中。源和目的操作数都可能为该方式:

    MOV AX,12A2H;//目的操作数寄存器寻址
    MOV AX,BX;//目的和源操作数都是寄存器寻址

    直接寻址

      数据放在存储器中,用变量和[常数]来指出段内16位偏移量,其中变量定义后存在存储器的代码段CS里。例如下面,假如DS=0700H,那么物理地址为07034H的单元变为78H,物理地址为07035H的单元变为56H;AL获得地址07034H的内容78H,AH获得变量VAR1指向的字节34H,BL获得VAR1+1指向的字节12H(VAR2指向的内容)。这里的变量相当于[112H]、[113H],其中112H,113H分别是VAR1和VAR2的段内偏移量,而变量的默认段可以看做是CS。

    ORG 100H        
    MOV [34H],5678H;//[34H]为直接寻址
    MOV AL,[34H];
    MOV AH,VAR1;//VAR1直接寻址
    MOV BL,VAR1+1;//VAR1+1直接寻址
    ret
    VAR1 DB 34H;//定义变量
    VAR2 DB 12H;

    寄存器间接寻址

      该方式下寄存器内容作为地址,指向存储器中的数据,用[寄存器名]来表示。可采用该方式的寄存器限定于BX、BP、SI、DI,BP的默认段地址是SS,其它三个则是DS。下面代码中BX和BP的值相同,但是由于默认段地址不同,1111H被赋到00100H地址区域,2222H被赋到10100H地址区域;最后由于指定BX使用SS段基地址,AX成功取到值2222H。

    MOV AX,0000H;
    MOV DS,AX;//DS段地址设定
    MOV AX,1000H;
    MOV SS,AX;//SS段地址设定
       
    MOV BX,0100H;//基址寄存器设定
    MOV BP,0100H;//基址指针寄存器设定
    MOV [BX],1111H;//[BX]寄存器间接寻址
    MOV [BP],2222H;//[BP]寄存器间接寻址
    MOV AX,SS:[BX];

    寄存器相对寻址

      相对寻址是在寄存器间接寻址的基础上加上一定的偏移地址。有[寄存器名+常量]、常量[寄存器名]、变量[寄存器名]等等。下面,AL和AH分别得到了012AH和012BH地址的内容;而最后两行是将变量自己的偏移量加到了BX值上作为新地址,因此尽管变量值等于2AH,但是最后计算出的地址并非是012AH和012BH。这里也可以将变量理解为[DISP]形式,则与BX组成[BX][DISP],其偏移地址为BX+DISP。

    MOV BX,0100H;
    MOV [012AH],1234H; 
    MOV AL,2AH[BX];//BX+2AH寄存器相对寻址
    MOV AH,2AH[BX+1H];//BX+2BH寄存器相对寻址
    MOV CL,VAR1[BX];//BX+OFFSET VAR1寄存器相对寻址
    MOV CH,[BX+VAR1+1];
    ret
    VAR1 DB 2AH;

    基址变址寻址

      即由基址寄存器BX、BP和变址指针寄存器DI、SI共同决定地址,形式固定为[基址][变址]。下列语句使得01001H地址内容变为1111H。

    MOV AX,0000H;
    MOV DS,AX;
    MOV BX,1000H; MOV DI,0001H; MOV [BX][DI],1111H;

    基址变址相对寻址

      即在基址变址寻址基础上加上一定地址偏移,同样可以使用常量或者变量作为偏移,方式同寄存器相对寻址。下面代码实现01011H地址内容变成1111H。

    MOV AX,0000H
    MOV DS,AX; MOV BX,1000H; MOV DI,0001H; MOV [BX][DI
    +0010H],1111H;//BX+DI+0010H基址变址相对寻址

    程序寻址

      除了数据需要寻址,指令代码也是要通过CS和IP来进行寻址的。正常情况,每执行完一条指令,IP会自动增加,更复杂的情况则来源于跳转指令。

    段内直接寻址

      即通过标号、寄存器值、常数、变量等方式直接指定新的16位IP偏移地址。下面的例子通过标号ADD1记录指令地址,JMP进行跳转,最后程序实现AL的无限循环自增。当然,也可以用常量等代替标号实现寻址。

    ADD1:ADD AL,01H; 
    JMP ADD1;

    段内间接寻址

      即将寄存器内容作为地址,到存储器中取数,取出的数作为新的16位IP地址。这类似于数据寻址中的寄存器间接寻址方式,同样地,寄存器只能使用BX、BP、DI、SI。但是,这里不能用方括号,而是使用WORD PTR,表示以寄存器值作为地址取数两个字节。以下代码跳转到地址为01000H的指令,而不是00000H处。

    MOV AX,0000H;
    MOV CS,AX;
    MOV BX,0000H; MOV [BX],1000H;
    //数据的寄存器间接寻址 JMP WORD PTR BX;//程序的间接寻址

    段间直接寻址

      借助标号实现跳转,但是该标号指向的是另一段的指令。另外,通过常量和变量已经不能实现段间转移。

    段间间接寻址

      也是将寄存器内容作为地址,读取4个字节作为CS和IP的值,其中IP获得两个低字节,CS获得两个高字节。下例中,BX保存了VAR1的偏移地址,最终IP获取3344H,CS获取1122H。

    MOV BX,OFFSET VAR1;
    JMP FAR PTR BX;//程序段间间接寻址
    ret            
    VAR1 DD 11223344H;

     

  • 相关阅读:
    MFC中 CListCtrl控件的使用及定位、选中
    在VC++6.0中,编译,调试都能通过,但运行到某一步的时候就报错的可能原因。
    存储IplImage结构体到STL中的vector中的问题
    VS工程,换电脑后出现的问题
    What is a Full Stack developer?
    [MB855]变砖解决
    ERP 开发过程中涉及到的算法 库存,工程,生产计划,固定资产计算方法
    定义枚举类型带有byte 的作用
    构造函数带有this和base的作用
    创建一个简单的WCF程序(转载)
  • 原文地址:https://www.cnblogs.com/kensporger/p/12505010.html
Copyright © 2020-2023  润新知