CPU寄存器与寻址方式


本文属于《 X86架构指令基础系列教程》之一,欢迎查看其它文章。

1 CPU寄存器

以下为X64架构下,CPU具备的通用目的寄存器情况。
在这里插入图片描述

  • X64为64位寻址,因此寄存器为64位,如红色框所示,具备rax~r15共16个寄存器;
  • X86为32位寻址,因此寄存器为32位,如蓝色框所示,具备eax~esp共8个寄存器;
  • 8086为16位寻址,因此寄存器为16位,如橙色框所示,具备ax~sp共8个寄存器。

X64将X86的8个通用寄存器扩展为64位,增加了8个新的通用64位寄存器。64位寄存器的名称都以字母“r”开头(当然,寄存器名称不区分大小写,也可以是“R”开头),例如,eax的64位扩展寄存器命名为rax,新增加的寄存器命名从r8到r15。
每个寄存器的低32位,低16位,低8位可在操作数中直接寻址。这包括像esi这样的寄存器,其低8位在以前是不能直接寻址的。

2 表达数据位置

汇编语言中用3个概念来表达数据的位置。

  • (1)立即数(idata)
    对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中),在汇编语言中称为:立即数(idata),在汇编指令中直接给出。

例:

mov ax,1
add bx,2000h
or bx,00010000b 
mov al,'a’
  • (2)寄存器
    指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。

例:

mov ax,bx
mov ds,ax
push bx
mov ds: [0],bx
push ds
mov ss,ax
mov sp,ax
  • (3)段地址(SA)和偏移地址(EA)
    指令要处理的数据在内存中,在汇编指令中可用[X]的格式给出EA,SA在某个段寄存器中。
    存放段地址的寄存器可以是默认的,比如:
mov ax, [0]
mov ax, [di]
mov ax, [bx+8]
mov ax, [bx+si]
mov ax, [bx+si+8]

等指令,段地址默认在 ds 中。

mov ax, [bp]
mov ax, [bp+8]
mov ax, [bp+si]
mov ax, [bp+si+8]

等指令,段地址默认在 ss 中。

存放段地址的寄存器也可以是显性给出的,比如以下的指令。

mov ax,ds: [bp]			含义:(ax)=((ds)*16+(bp))
mov ax,es: [bx]			含义:(ax)=((es)*16+(bx))
mov ax,ss: [bx+si]		含义: (ax)=((ss) *16+ (bx) + (si))
mov ax,cs: [bx+si+8]	含义: (ax)=((cs) *16+ (bx) + (si) +8)

3 寻址方式

以下为8086 CPU支持的常见寻址方式,有以下五种。
在这里插入图片描述
当数据存放在内存中的时候,我们可以用多种方式,来给定这个内存单元的偏移地址,这种定位内存单元的方法,一般被称为寻址方式
接下来,我们对每种寻址,进行举例说明。

3.1 直接寻址

指令形式:[idata],比如:

mov ax, [2000h]

段地址默认在 ds 中,含义:(ax) = ((ds) * 16 + 2000h),表示将ds段寄存器中基址 * 16 + 2000h,所指向的内存,拷贝到ax寄存器中,长度为2字节。

3.2 寄存器间接寻址

[bx] 为例,比如:

mov ax, [bx]

段地址默认在 ds 中,含义:(ax) = ((ds) * 16 + (bx)),表示将ds段寄存器中基址 * 16 + bx寄存器中偏移,所指向的内存,拷贝到ax寄存器中,长度为2字节。
相比[idata]直接寻址,多了一步,即需要先读取bx寄存器中的偏移,因此叫间接寻址。

3.3 寄存器相对寻址

[bx+idata] 为例,比如:

mov ax, [bx+2000h]

段地址默认在 ds 中,含义:(ax) = ((ds) * 16 + (bx) + 2000h),表示将ds段寄存器中基址 * 16 + bx寄存器中偏移 + 2000h,所指向的内存,拷贝到ax寄存器中,长度为2字节。
相比[bx]间接寻址,又多了一步,即额外还要加一个相对bx寄存器的常量偏移,因此叫寄存器相对寻址。

3.4 基址变址寻址

[bx+si] 为例,比如:

mov ax, [bx+si]

段地址默认在 ds 中,含义:(ax) = ((ds) * 16 + (bx) + (si)),表示将ds段寄存器中基址 * 16 + bx寄存器中偏移 + si寄存器中偏移,所指向的内存,拷贝到ax寄存器中,长度为2字节。

3.5 相对基址变址寻址

[bx+si+idata] 为例,比如:

mov ax, [bx+si+2000h]

段地址默认在 ds 中,含义:(ax) = ((ds)*16 + (bx) + (si) + 2000h),表示将ds段寄存器中基址 * 16 + bx寄存器中偏移 + si寄存器中偏移 + 2000h,所指向的内存,拷贝到ax寄存器中,长度为2字节。
相比[bx+si]寻址,多了一步,即额外还要加一个相对[bx+si]寄存器的常量偏移,因此叫相对基址变址寻址。

3.6 按比例变址寻址(SIB)

上面5种寻址方式是8086以上的CPU,均具备的基本寻址方式。
按比例变址寻址,也称为"scale-index-base"(SIB)寻址,是仅在32和64位CPU架构才支持的内存寻址方式。
在这里插入图片描述
在SIB寻址中,地址计算分为三个部分:基址、索引和比例因子。

  • 基址(base),包含一个或多个寄存器,用于指定基址。在指令中,可以使用一个或多个寄存器来作为基址。这些寄存器可以是通用寄存器(如RAX、RBX等)或系统寄存器(如CR3等)。

  • 索引(index),包含一个或多个寄存器,用于指定在基址上的偏移量。在指令中,可以使用一个或多个寄存器来作为索引。这些寄存器可以是通用寄存器(如RCX、RDX等)或系统寄存器(如RSI、RDI等)。

  • 比例因子(scale),是一个常数,用于指定比例因子。在指令中,可以使用一个字节或多个字节来表示比例因子。比例因子的值可以是1、2、4、8等,具体取决于指令和操作的要求。

  • 位移量(displacement),可选,可以是立即数(常量)或寄存器值,它表示相对于基址的偏移量。

通过将基址、索引和比例因子结合起来,可以计算出最终的内存地址。
计算公式为:内存地址 = 基址 + 索引 * 比例因子 + 位移量(若存在)。其中,“+”表示加法运算,“*”表示乘法运算。

按比例变址寻址,我们可以用[- -][- -]符号来表示。
例如:

mov eax,[ebx+ecx*2]

含义:(eax) = ((ebx) + (ecx) * 2),表示将ebx寄存器中基址 + ecx寄存器值 * 2,所指向的内存,拷贝到eax寄存器中,长度为4字节;位移量为0。

mov eax,[ebx+ecx*2+100h]

含义:(eax) = ((ebx) + (ecx) * 2 + 100h),表示将ebx寄存器中基址 + ecx寄存器值 * 2 + 100h,所指向的内存,拷贝到eax寄存器中,长度为4字节;位移量为100h。


参考文档:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值