代码之家  ›  专栏  ›  技术社区  ›  Tryer

Linux上x86的内存寻址模式解释

  •  0
  • Tryer  · 技术社区  · 7 年前

    我正在看完 Programming from the ground up by Jonathan Bartlett . 作者讨论了存储器寻址方式,指出存储器地址引用的一般形式是:

    ADDRESS_OR_OFFSET (%BASE_OR_OFFSET, %INDEX, MULTIPLIER)

    如果最终地址是这样计算的:

    FINAL_ADDRESS = ADDRESS_OR_OFFSET + %BASE_OR_OFFSET + MULTIPLIER * %INDEX .

    同时也指出,如果任何一个部分被遗漏,则在方程中用零代替。 ADDRESS_OR_OFFSET MULTIPLIER 必须是常量,而其他元素则必须是寄存器。这些似乎是唯一规定的一般规则。

    到目前为止,一切都很好。

    然后,作者讨论了间接寻址方式,并举例说明:

    movl (%eax), %ebx

    它移动存储在 eax 登记入 ebx 寄存器。

    为了工作, (%eax) 应解释为 0(%eax,0,0) 而不是 0(0,%eax,0) . 是否有其他规则强制执行此解释?

    1 回复  |  直到 7 年前
        1
  •  2
  •   fuz    7 年前

    书中的解释不完全正确。x86体系结构具有以下32位寻址模式:

    $imm                         immediate     result = imm
    %reg                         register      result = reg
    disp(%reg)                   indirect      result = MEM[disp + reg]
    disp                         direct        result = MEM[disp]
    disp(%base, %index, %scale)  SIB           result = MEM[disp + base + index * scale]
    

    在SIB(scale/index/base)和间接寻址模式中, disp 可以忽略为0字节的位移。在SIB寻址模式下,另外 base index 0刻度、0索引可以省略;刻度实际上不能省略。注意,当我说leave out时,只有值被省略;逗号被保留。例如, (,,1) 表示无位移、无基、无索引和1个小数位数的sib操作数。

    在64位模式下,A rip -另外还提供相对寻址模式:

    disp(%rip)                   rip relative  result = MEM[disp + rip]
    

    这种寻址模式对于编写位置无关的代码很有用。

    16位模式有不同的寻址模式,但它们并不重要,所以我不打算详细介绍它们。

    例如:这很容易理解,因为它实际上是 间接的 寻址模式,而不是 同胞 寻址模式 eax 作为寄存器,没有移位。