在 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)。有了这个,如果你需要访问内存,你可以在寄存器中计算你想要的任何地址,并用它来进行访问。
    它还可以通过使用内存代替直接寄存器操作数,并通过用算术构造值来代替立即操作数。但是,对于实际的指令集,您仍然需要立即操作数来有效地加载地址,如果您不想要仅指针寄存器,则需要寄存器操作数。

    除了寄存器间接寻址之外的所有其他寻址方式都是为了方便起见,它们确实非常方便:
  • 如果您只需要访问内存中的固定变量,则立即寻址可为您节省一个寄存器。
  • Base + offset 对于访问对象成员非常有用:您可以将基地址保存在寄存器中,并使用固定偏移量访问各个成员。不需要中间计算或寄存器来保存成员地址。
  • 类似地,索引寻址用于访问数组:您只需更改索引寄存器即可访问数组中的任何值。
  • 使用比例尺,您可以访问多字节变量(例如: int )数组,而无需额外的寄存器或计算。
  • 可以使用所有内容的组合来访问对象中的数组成员,同时仍保留基指针以供潜在访问对象中的其他成员。

  • 这些寻址模式不需要来自 CPU 的大量计算:只需添加和移位。考虑到 x86 可以在每个周期进行一次乘法运算,这些操作是微不足道的,但仍然非常方便。

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

    10-10 16:31