跳到主要内容

CPU 的七种寻址方式

· 阅读需 9 分钟
不如怀念
Web 前端工程师 (Web Front-end Engineer)

最后更新于 2016-05-05 01:53:00

CPU 获取数据的方式不仅仅一种,多种方式也为不同数据的获取提供了不同的效率考量,保证了寻址效率与指令的灵活性。

CPU 寻址方式

数据一般均存储在外存(硬盘)中,在需要的时候,会将数据先从外存读入内存(存储器)中,然后 CPU 再直接从内存(缓存)中获取。获取的数据有时候会直接使用;而有时候会先存入 CPU 内部寄存器,稍后再从寄存器中获取。所以,CPU 获取数据的方式是多样化的。

在为了保证寻址效率指令灵活性的基础上,设计有 7 种寻址方式,他们分别是:

  • 立即(数)寻址
  • (存储器)直接寻址
  • 寄存器(直接)寻址
  • 寄存器间接寻址
  • 寄存器相对寻址
  • 基址、变址寻址
  • 基址、变址、相对寻址

下面结合早期 Inter 的微处理器 8088(8086) 以及汇编指令来举例说明这七种寻址方式的判断方法和原理。

立即(数)寻址

源操作数直接包含在指令中,与操作码一起放在代码段区域中。CPU 读出指令操作码后,在其下面的地址中可立即读出源操作数。

立即寻址方式的操作也称为立即数。立即数可以是 8 位,也可以是 16 位。

MOV AL, 05H     (8位立即数)
MOV DX, 8000H (16位立即数)

注意:源操作数才可以是立即数,目的操作数为立即数是违法操作。

MOV 05H, AL     (违法指令)

原因:这就和高级语言中变量赋值一样,=号左边必须是变量名,而不能是常数。

立即数寻址方式通常用来给寄存器赋初值。

(存储器)直接寻址

操作数存放在存储器(内存)中,在指令给出的是该操作数的有效地址(段内偏移地址)。操作数通常存放在数据段中,默认的段地址存放在 D 段寄存器中。

操作数的内存地址:DS 段地址 ×16(左移 4 位)+16 位偏移地址=20 位内存地址

MOV BX, [2000H]    (假设段地址 DS=1000H)
内存地址:1000H×16+2000H=12000H

注意:段地址也有可能不在 DS 中,此时指令中会给出存放段地址的寄存器号(段超越前缀不可省略)。

MOV ES:[2000H], AX  (段地址存放在ES寄存器中)

寄存器(直接)寻址

操作数存放在 CPU 内部寄存器中,例如 AX、BX、CX、DX 等。

MOV DS, AX
MOV AL, BL

注意:由于 AX 是累加器,如果将结果存放在 AX 中,即将 AX 作为目的操作数存放位置,通常指令的执行时间要短一些。

寄存器寻址方式,减少了读/写存储器单元的次数,所以,使用寄存器寻址方式的指令一般执行速度比较快。

寄存器间接寻址

操作数存放在存储器(内存)中,有效地址(段内偏移地址)存放在内部寄存器 SI、DI、BX、BP 之一中,由于段地址可存放在 DS 和 SS 中又分为两种:

  • 若段内偏移地址存放于 SI、DI、BX 之一中,默认段地址存放在 DS 寄存器中。

exp:

MOV AX, [SI]
MOV AX, [DI]
MOV AX, [BX]

操作数的内存地址:DS 段地址 ×16(左移 4 位)+[SI][di][BX]偏移地址=20 位内存地址。

  • 若段内偏移地址存放于 BP 中,默认段地址存放在寄存器 SS(堆栈段)中。

exp:

MOV BX, [BP]

操作数的内存地址:SS 段地址 ×16(左移 4 位)+[BP]偏移地址=20 位内存地址。

寄存器相对寻址

操作数存放在存储器(内存)中,有效地址(段内偏移地址)存放在内部寄存器 SI、DI、BX、BP 之一中,由于段地址存放在 DS、SS 之一中,所以也可分为两类,不再细说,类比寄存器间接寻址方式即可。

相比于寄存器间接寻址方式,寄存器相对寻址的不同之处在于多了一个 8 位或 16 位的带符号常数偏移量。

MOV AL, [SI-200H]

操作数的内存地址:SS 或 DS 段地址 ×16(左移 4 位)+[BP]或[SI][di][BX]偏移地址+常数偏移量=20 位内存地址。

MOV AL, [SI-2]    (假设 DS=3000H,SI=1000H)
内存地址:3000H×16+1000H-2=30FFEH

基址、变址寻址

操作数存放在存储器(内存)中,基址存放在内部寄存器 BX、BP 之一中,变址存放在内部寄存器 SI、DI 之一中,由于段地址存放在内部寄存器 SS、DS 之一中,所以也可分为两类,类比寄存器间接寻址方式即可。

操作数内存地址:SS 或 DS 段地址 ×16(左移 4 位)+[BP]或[BX]基址+[SI][di]变址=20 位内存地址

MOV AL, [BP][DI]    (假设 SS=8000H,BP=1000H,DI=0500H)
内存地址:8000H×16+1000H+0500H=81500H

基址、变址、相对寻址

操作数存放在存储器(内存)中,基址存放在内部寄存器 BX、BP 之一中,变址存放在内部寄存器 SI、DI 之一中,由于段地址存放在内部寄存器 SS、DS 之一中,所以也可分为两类,类比寄存器间接寻址方式即可。

相比于基址、变址寻址方式,基址、变址、相对寻址的不同之处在于多了一个 8 位或 16 位的带符号常数偏移量。

MOV AL, 1000H[BP][DI]

操作数内存地址:SS 或 DS 段地址 ×16(左移 4 位)+[BP]或[BX]基址+[SI][di]变址+常数偏移量=20 位内存地址

MOV AL, 0010H[BX][SI]  (假设 DS=6000H,BX=5000H,SI=0300H)
内存地址:6000H×16+5000H+0300H+0010H=65310H

寻址类别

这七种 CPU 寻址方式中,可以根据操作数是否在存储器(内存)中分为两类:内存寻址方式非内存寻址方式。其中内存寻址方式包含:

  • (存储器)直接寻址
  • 寄存器间接寻址
  • 寄存器相对寻址
  • 基址、变址寻址
  • 基址、变址、相对寻址

结语

通常来说,要根据汇编指令判断寻址方式,需要知道目标 CPU 是什么,以及 CPU 内部寄存器的设计布局是什么,这样才能正确判断出寻址方式。以上的七种寻址方式说明全部是基于 Inter 的 8086(8088)处理器的。