8086寻址方式
概述
一条汇编指令包含了操作码和操作数两部分,而操作数又分为目的操作数(DST)和源操作数(SRC)两种。汇编指令就是操作码与操作数的结合,有的操作码需要两个操作数(即DST和SRC)有的只需要一个操作数(例如PUSH),还有的不需要操作数(例如CLI)。
这种差异性便是寻址方式的不同造成的,所谓寻址便是确定如何寻找操作数的过程。
不管指令需要结合多少个操作数,指令执行过程中数据的流向是唯一的,那就是从SRC -> DST
。并且在数据传递的过程中必须保障SRC
和DST
长度大小明确且一致。
指令系统的寻址主要包括两类:
- 数据的寻址方式:寻找指令所操作数据的方式
- 转移地址的寻址方式:寻找转移指令所需的程序地址
数据的八种寻址方式:
- 立即数寻址
- 寄存器寻址
- 存储器寻址
- 直接寻址
- 寄存器间接寻址
- 寄存器相对寻址
- 基址变址寻址
- 基址变址寻址且相对寻址
- 隐含寻址
立即数寻址
MOV AX, 100H ; 十六进制立即数
MOV BX, 1010 ; 十进制立即数
MOV AX, 12Q ; 八进制立即数
MOV AX, 0101B ; 二进制立即数
立即数只能作为源操作数(SRC)使用,无法作为目的操作数。立即数所占据的内存大小由目的操作数决定。且立即数本身长度不得超出目的操作数长度。
MOV AL, 10H ; 10H占据一个Byte的空间
MOV AX, 10H ; 10H占据一个Word的空间
MOV AL, 1010H ; ❌ 1010H占据一个Word的空间无法放入一个Byte的寄存器中
MOV 1010H, AX ; ❌ 立即数无法作为DST
注:CS寄存器在立即数寻址过程中无法作为目的操作数使用。
寄存器寻址
MOV AX, BX ; 将BX的内容转移到AX中
ADD AX, BX ; 将AX和BX中的内容相加结果存储在AX中
MOV AX, AL ; ❌不推荐使用,长度不一致
MOV AL, AX ; ❌不推荐使用
存储器寻址
存储器寻址是指操作数存放于存储器中,寻找这类操作数可以通过一下五类寻址方式找到。
8086CPU具有20根地址线,内存地址的确定是通过段地址+偏移地址
实现的。当前数据段的段地址存放于DS
寄存器中。寻址时一般只提供偏移地址即可。
1.直接寻址
; 存储器 ----> 寄存器
MOV AX, [1000H] ; 内存(DS:1000H)开始寻找一个字的数据传输到AX寄存器中。
; 寄存器 ----> 存储器
MOV [1000H], AX ; 将AX寄存器中的数据传送到内存(DS:1000H)处
; 存储器 ---/--> 存储器
MOV [1000H], [0010H] ; ❌
若不使用DS寄存器中的数据作为段地址,也可以使用ES寄存器作为数据段的段地址。
MOV AX, ES:[1000H]
2. 寄存器间接寻址
寄存器寻址与直接寻址很相似,数据依然保存在存储器单元中,只不过存储单元的偏移地址存放于寄存器中,所以被称为寄存器间接寻址
。
并不是所有的寄存器都可以用来进行寻址,能够参与间接寻址的寄存器只有:BX
, SI
, DI
, BP
,其中BX
, SI
, DI
默认的段地址为DS
指向的数据段,BP
默认的段地址为SS
指向的堆栈段。
MOV AX, [BX] ; 实际操作数地址 => DS:BX
MOV AX, [BP] ; 实际操作数地址 => SS:BP
MOV [BX], AX ; 将AX中的数据 => DS:BX
MOV [BP], AX ; 将AX中的数据 => SS:BP
3.寄存器相对寻址(伪指令写法)
寄存器相对寻址是在寄存器间接寻址的基础之上进行,其形式为:MOV DST [REG] + DISP
,其中[REG] + DISP
的这种形式称为寄存器相对寻址,操作数在存储器中的偏移地址为寄存器的值 + DISP。
MOV AX, [BX] + 02H
MOV [BX] + 02H, AX
MOV [BP] + 03H, AL
MOV AL, [BP] + 03H
4.基址变址寻址
基址变址寻址,包括后面的基址变址且相对寻址,其数据段地址由基址寄存器决定,即BX
, SI
, DI
作为基址寄存器时,数据在DS
指定的的数据段中,BP
作为基址寄存器时,数据在SS
指向的堆栈段。
MOV AX, [BX][SI]
MOV [BX][SI], AL
5.基址变址且相对寻址
MOV AX [BX][SI] + 12H
MOV [BX][SI] + 12H AL
隐含寻址
有些指令无需指明操作数,或者只有一个操作数。这类指是隐含了操作数,这类寻址的方式称为隐含寻址。
类似的指令有:CLI
, MUL
, PUSH
。