assembly - 计算所需的最小寻址模式数量是多少?

标签 assembly x86 cpu-registers cpu-architecture addressing

在 x86 汇编器中,假设您有

  • 立即寻址模式分配号码
  • 寄存器的寄存器寻址模式
  • 内存地址的直接寻址模式

为什么需要索引和基指针寻址模式? 据我所知,每个都可以用循环替换。

此外,间接模式似乎也不太有用,因为您可以简单地使用直接模式来引用内存地址。首先访问包含指向内存地址的指针的寄存器的目的是什么?

简而言之,哪些寻址模式是真正必要的?

最佳答案

虽然理论上“寻址模式”可以用来指代操作数类型,但由于它不涉及地址,所以有点令人困惑。 Intel 手册使用“寻址模式”来指代内存寻址,我将使用这个定义。

在汇编中,操作数可以是:

  • 立即值
  • 一个寄存器
  • 内存中的一个值(这里的操作数是地址)

在x86架构中,“寻址模式”仅针对最后一类操作数:内存操作数(地址),指的是可用于计算地址的方法。寻址模式可以概括为一个可配置的寻址模式:

address = REG_base + REG_index*n + offset

REG_baseREG_indexnoffset 都是可配置的,并且都可以省略(但是您显然,至少需要一个)。

address = offset 称为立即寻址、直接寻址或绝对寻址。
address = REG_base称为寄存器间接寻址。
address = REG_base + REG_index 称为基址加索引寻址。
同样,您可以添加偏移量 (offset) 和比例 (n)。

严格来说,您只需要一种模式即可完成所有操作:寄存器间接寻址(address = REG)。这样,如果您需要访问内存,您可以在寄存器中计算出您想要的任何地址,并使用它来进行访问。 它还可以通过使用内存来替换直接寄存器操作数,以及通过算术构造值来替换立即操作数。然而,对于实际的指令集,您仍然需要立即数操作数来有效地加载地址,并且如果您不需要仅指针寄存器,则需要寄存器操作数。

除了寄存器间接寻址之外的所有其他寻址模式都是为了方便起见,它们确实非常方便:

  • 如果您只需访问内存中的固定变量,立即寻址可以为您节省一个寄存器。
  • 基址+偏移量对于访问对象成员非常有用:您可以将基地址保存在寄存器中并使用固定偏移量访问各个成员。无需中间计算或注册来保存成员(member)地址。
  • 同样,索引寻址用于访问数组:您只需更改索引寄存器即可访问数组中的任何值。
  • 通过比例,您可以访问多字节变量(例如:int)数组,无需额外的寄存器或计算。
  • 所有内容的组合可用于访问对象中的数组成员,同时仍保留基指针以供潜在访问对象中的其他成员。

这些寻址模式不需要 CPU 进行太多计算:只需加法和移位。考虑到 x86 每个周期都可以执行乘法,这些操作虽然微不足道,但仍然非常方便。

关于assembly - 计算所需的最小寻址模式数量是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35221379/

相关文章:

performance - 生产者-消费者在超同级与非超同级之间共享内存位置的延迟和吞吐量成本是多少?

assembly - 128位至512位寄存器有什么用?

linux - 将在 linux 中运行汇编代码的结果重定向到文本文件

linux - linux中系统调用机制的疑惑

winapi - 如何让这两行在 cmd 控制台中的不同行上打印

linux - qemu 中的 x86 linux 内核开发

java将对象保存在CPU寄存器中

c++ - 如何隐藏类中的寄存器地址

assembly - 操作码 '89' 的 x86 Modrm/Sib/位移字节

assembly - NASM 汇编器 - 如何确保函数标签不会被额外执行一次?