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

时间:2019-01-06 11:01:28

标签: linux assembly x86

我正在阅读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_OFFSETMULTIPLIER必须是常量,而其他元素必须是寄存器。这些似乎是指定的唯一通用规则。

到目前为止,太好了。

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

movl (%eax), %ebx

将存储在eax寄存器中的地址的值移到ebx寄存器中。

要使其正常工作,应将(%eax)解释为0(%eax,0,0),而不是0(0,%eax,0)。是否有其他规则可以强制这种解释?

1 个答案:

答案 0 :(得分:2)

书中的解释不是100%正确。 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(比例/索引/基数)和间接寻址模式中,disp可以省略0字节位移。在SIB寻址模式下,baseindex可以省去0标度和0索引;规模实际上不能被忽略。请注意,当我说“ leave out”时,只剩下值。 例如,(,,1)的意思是“ SIB操作数,无位移,无基数,无索引和小数位数。”

在64位模式下,还可以使用rip相对寻址模式:

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

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

16位模式具有不同的寻址模式,但是它们并不重要,因此我不再赘述。

因此,对于您的示例:这很容易理解,因为它实际上是一种间接寻址模式,而不是一种以eax作为寄存器且没有编号的 SIB 寻址模式。位移。