80x86的7种寻址方式
所需知识点:一个寄存器可以储存16bit信息,即1个字,也可以分成2部分(高位字节和低位字节),每部分存储8bit即1字节
在8086中只有bx,bp,si,di可以在"[…]"中进行内存单元的寻址
1.立即寻址
操作数在指令中,紧跟在操作码之后,这样的操作数成为立即数
例如:
MOV AL,12H
MOV AX,1234H
2. 直接寻址
用一个常量来表示地址,可用于直接定位一个内存单元。
操作数的地址中的偏移量直接跟在操作码之后,默认情况下基址存放在DS中,这个时候不需要加前缀。如果是加了别的前缀,如ES,则表示基址在ES中。
例如:
mov ax,[40h]
3.寄存器寻址
操作数在CPU的寄存器中,指令指定寄存器号,这种寻址速度快,它不需要访问存储器中的操作数,因为所有的操作数都在寄存器中。
例如:
mov ds,ax
mov al,dh
4.寄存器间接寻址
用一个变量表示地址
操作数在存储器中,操作数有效地址在SI,DI,BX,BP这四个寄存器之一中,在一般情况下,如果有效地址在SI,DI和BX中,则以DS段寄存器之内容为段值。如果有效地址在BP中,则以SS段寄存器之内容为段值
例如:
mov ax,[bx] 或 mov ax,[si]或 mov ax,[di]-----DS基址
mov ax,[bp]-----SS基址
5.寄存器相对寻址方式
用一个变量和一个常量表示地址
注:[bx+count]=[bx].count=coount[bx]
(1)基址相对寻址
对于BX寄存器来说,使用DS作为基址寄存器.例如:mov ax,count[bx] ------DS基址
对于BP寄存器来说,使用SS作为基址寄存器.例如:mov ax,count[bp] ------SS基址
(2)变址相对寻址
注:si,di与bx的唯一区别是si,di不可拆分为2部分
mov ax, count[si]
该例子的物理地址计算是这样的:物理地址=16D(DS)+(si)+count*
在编程时,我们可以将一组内存单元定义为一个段,这个完全取决于我们
但段的长度必须<=64kb的连续地址,且起始地址为16的倍数
如:123B0H—123B9H
这个段内存的段地址就是1230H,长度就是10个字节了,5个字
那么问题来了——为什么要*16D?
80x86将16位地址总线扩展成了20位地址,段地址左移4位即乘16
比如段地址ds=2000H,偏移地址bx=0040H,则物理地址=20040H
6.基址变址寻址
用两个变量表示地址,注意只有4种组合方式
例如:
mov ax,[bx][si] 原变址寻址
mov ax,[bp][si]
mov ax,[bx][di] 目的变址寻址
mov ax,[bp][di]
可以用来表示数组
;实现将数组si复制到数组di
mov ax,2000H
mov ds,ax
mov si,00H
mov di,10H
mov bx,00H
s: mov ax,si[bx]
mov di[bx],ax
add bx,1H
loop s;循环给bx赋值
7.相对基址变址寻址
用两个变量和一个常量寻址
EA=DS16+BX+SI(或DI)+DISP(8位或16位偏移量)
EA=SS16+BP+SI(或DI)+DISP(8位或16位偏移量)
例如:
mov ax, [bx+si+count]
可以这样子记忆:
基址:出现[ax]、[bx]等
变址:出现[si]、[di]
相对:出现常量[count]