一、总括
(1)立即寻址方式
(2)寄存器寻址方式
(3)存储器寻址方式
1、直接寻址方式 2、寄存器间接寻址方式 3、寄存器相对寻址方式
4、基址变址寻址方式 5、相对基址变址寻址方式
二、七种寻址方式
(1)立即寻址方式
直接将操作数(又称立即数)写在指令中,可以用于直接指定一个常数给寄存器。
1、立即寻址方式只能用于源操作数字段
2、立即数的大小是不确定的,但是和目的操作数保持一致(这里会有一些目的操作数与源操作数的错误,在下一章会有提到)
MOV AX,6
MOV AL,6
MOV AX,12AF
上述操作都对,值得注意的是,第一句立即数是十六位的,第二句是八位的
(2)寄存器寻址方式
操作数就是寄存器的值,将一个寄存器的值送给另一个寄存器
MOV AX,BX
指令执行后,AX=BX,BX,保持不变
(3)存储器寻址方式
前两种方式在执行过程中,操作数都在CPU内部的寄存器里,不用到存储器中去找操作数;而这一类方式的操作数都在存储器中,CPU必须经过系统总线访问存储器,在执行指令阶段通过采用不同的寻址方式求得操作数地址,才能取得操作数。由于存储器各个段的段基址已分别由各个段寄存器存放,因此我们只需要根据操作数的偏移地址就可求出其物理地址
<1>直接寻址方式
操作数的有效地址(EA,又称偏移地址)就在指令中;
MOV AX,DS: [2000H]
存储器可以进行读写操作,即MOV指令的两个操作数都可以分别是存储单元,CPU的寄存器;
MOV AX,DS: [4040H] ;读操作
MOV DS: [4050H], AX ;写操作
该方式也可使用符号地址作为有效地址,用变量名定义一个存储单元,这个时候可以是用伪指令DW,DB等定义存储单元名字(无需加上前缀DS:)
VALUE DW 5678H
MOV AX, VALUE
MOV AX, [VALUE]
这里两种书写方式都对,汇编程序都会理解为将value所指向的内存地址的数据送给AX
这里默认了是在数据段DS上,也可以通过段超越前缀放在别的段,
MOV AX, ES:[VALUE] //这里的就是操作数放在别的段了
<2>寄存器间接寻址方式
操作数的有效地址在寄存器中,与寄存器寻址方式不同的是,该方式把寄存器的内容作为操作数的地址,操作数本身还是在内存里,故称寄存器间接寻址。注意这里只能使用BX,BP,SI,DI;
相应的物理地址计算方式如下(默认情况下,不加段前缀):
操作数的物理地址=(DS)*10H+(BX)(BP,SI相同)
操作数的物理地址=(SS)*10H+(BP)//堆栈段
该方式形如以下几种:
MOV AX,[BX] ;默认DS段寄存器存放段基址
MOV AX,[BP] ;默认SS段存放段基址
MOV ES:[DI],AX ;指定ES寄存器存放段基址
<3>寄存器相对寻址方式
操作数的有效地址是一个寄存器的值和位移量之和,在寄存器间接寻址的基础上加上了位移量,位移量可以是符号,也可以是具体的数字;位移量一般是十六位或者八位的;适合用于访问一维数组,寄存器的值可作为数组下标(或元素的位置,利用修改寄存器的值来定位数组的各个元素)。
相应的物理地址计算方式如下(默认情况下,不加段前缀):
操作数的物理地址=(DS)*10H+(BX)+位移量(BP,SI相同)
操作数的物理地址=(SS)*10H+(BP)+位移量//堆栈段
具体格式形如
MOV AX,ARRY[BX] ;这里的ARRY指定是符号地址,即位移量,这里进行计算的是符
MOV AX, [ARRY][BX] ;号地址,而不是该地址存储的值
MOV AX, [ARRY+BX]
MOV AX, [BX].8H
MOV AX, [BX+8H]
<4>基址变址寻址方式
操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和,允许使用的基址寄存器为BX和BP,变址寄存器为SI和DI;
相应的物理地址计算方式如下(默认情况下,不加段前缀):
操作数的物理地址=(DS)*10H+(BX)+SI(或DI)
操作数的物理地址=(SS)*10H+(BP)+SI(或DI)//堆栈段
具体格式形如:
MOV AX, [BX][SI]
MOV AX, [BP][DI]
MOV AX, ES: [BX][DI]
MOV [SI+BP],AL
<5>相对基址变址寻址方式
操作数的有效地址是一个基址寄存器的值和一个变址寄存器的值以及一个位移量之和
相应的物理地址计算方式如下(默认情况下,不加段前缀):
操作数的物理地址=(DS)*10H+(BX)+SI(或DI)+位移量
操作数的物理地址=(SS)*10H+(BP)+SI(或DI)+位移量//堆栈段