8086 处理器寻址方式

请注意:本文编写于 ,其中某些信息可能已经失去时效性。

前言

本文主要描述了何为寻址,寻址能力的计算以及 8086 处理器的寻址方式有哪些。

寻址

什么是寻址?

内存中每一个字节(8bit)都有一个对应的内存地址,CPU 去访问某一具体内存地址的过程称为寻址。

寻址能力与什么有关?

CPU 的寻址能力一般使用寻址空间来表示,寻址空间的大小决定了 CPU 可支持的最大内存容量,以字节为单位。寻址空间的大小由地址总线的地址寄存器宽度(位数)决定,假设地址总线位数为 N 位,则寻址空间为 2 的 N 次方字节(因为计算机使用的是二进制所以是 2 的 N 次方)。

特殊的 8086 处理器

8086 处理器有 20 位地址总线,可传送 20 位的地址,寻址空间为 1M。

而 8086 处理器是 16 位结构的处理器即 8086 内部的寄存器位数为 16 位,如果按照这个数据处理能力 8086 只能发送出 16 位的地址,表现出的寻址能力只有 64 KB。

为了解决上述问题,在 8086 处理器内部采用了一种使用两个 16 位地址(段地址:偏移地址)合成一个 20 位物理地址的方案。

具体计算公式为:物理地址 = 段地址左移四位 + 偏移地址

指令

在汇编语言中,一般的指令格式为:指令代码 目的操作数,源操作数

目的操作数和源操作数统称为操作数,而寻址方式的主要表现形式就是体现在两个操作数的表现形式上

8086 处理器的寻址方式

8086 处理器有七种基本寻址方式:

寄存器寻址

指令执行时,操作数位于寄存器中,可以直接从寄存器中获取。

1
2
3
mov ax,cx     ; 此条指令中目的操作数和源操作数使用的都是寄存器寻址
add bx,0xf000 ; 此条指令中目的操作数使用的是寄存器寻址,源操作数使用的是后面要介绍的直接寻址
inc dx ; 这是一条比较特殊的指令,它有目的操作数,这里使用的是寄存器寻址

立即寻址

立即寻址又称为立即数寻址,指的是操作数为立即数的寻址方式。

所谓立即数指的是直接包含在指令中且紧跟在操作码后可以立即从指令中获取的操作数。

在立即寻址中立即数可以是 8位的,也可以是 16位的(注意我们的大前提是在 8086 处理器下)。这种寻址方式主要用于给寄存器或存储单元赋初始值,立即寻址是这七种基本寻址方式中速度最快的寻址方式。

注:在实例代码中会有一个特殊的立即寻址例子。

1
2
mov ax,oxf000   ; 此条指令中目的操作数使用的是寄存器寻址,源操作数采用的是立即寻址
mov ax,label_a ; 注意此条指令的源操作数,它采用的也是立即寻址,这里的 `label_a` 虽然是一个标号但是标号是数值的等价形式,它代表了所在位置的汇编地址,在编译阶段被转换为一个立即数

内存寻址

寄存器寻址的操作数位于寄存器中,立即寻址的操作数位于指令中,是指令的一部分。这是两种速度比较快的寻址方式,但它们也有局限性:一方面,我们不可能总是知道要操作的数是多少,因此也就不可能总是在指令上使用立即数;另一方面,寄存器的数量有限,不可能总指望在寄存器之间来回传递数据。

考虑到内存容量大,所以在指令中使用内存地址来操作内存中的数据是比较理想的方案。

在正式介绍内存寻址之前需要先理解一个概念:有效地址

有效地址(Effective Address,EA) = 位移量(disp) + 基址(base) + 变址(index)

位移量:存放在指令中的数,但它不是一个立即数,而是一个地址,可以用变量或标号标识
基址:存放在基址寄存器(BX,BP)中,有效地址的基址部分
变址:存放在变址寄存器(SI,DI)中,有效地址的变址部分

直接寻址

寄存器间接寻址

寄存器相对寻址

基址变址寻址

相对基址变址寻址