CPU 的七种寻址方式
内容列表
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)处理器的。