【问题标题】:what does "mov offset(%rip), %rax" do?“mov offset(%rip), %rax”是做什么的?
【发布时间】:2015-06-07 22:16:54
【问题描述】:

rax 是获取偏移量加上这条指令的地址,还是下一条?从微码的角度来看,如果答案是下一条指令,可能会更容易。

【问题讨论】:

    标签: assembly x86-64 att addressing-mode relative-addressing


    【解决方案1】:

    下一个。这是 x86 的一般规则(另见分支)。

    在英特尔的手册第 2 卷第 2.2.1.6 节 RIP-Relative Addressing 中:

    一种新的寻址形式,RIP-relative(相对指令指针)寻址,是在 64 位模式下实现的。下一条指令的 64 位 RIP 加上位移就形成了一个有效地址。

    【讨论】:

    • x86 中的几乎所有东西都以这种方式工作。例如,jmp 指令的立即值是与下一条指令的位移。
    • 有趣——但是 RIP 相对寻址究竟有什么用处?
    • @AlexD 很多东西,通常都是对数据部分的引用等等
    • 全局变量,换句话说?但是为什么要使用相对于 RIP 的地址来访问全局呢?为什么不直接使用常量地址?
    • @AlexD:因为 RIP 相对寻址模式比 32 位绝对寻址模式短。 32 位模式有 2 种冗余方式来编码 [disp32]。 x86-64 将非 SIB 版本重新用作 [rip + rel32],而将没有基数或索引的 ModRM+SIB 编码保留为 [disp32]。主要是 disp32 绝对地址仅对索引静态数组有用:32-bit absolute addresses no longer allowed in x86-64 Linux?。但是 32 位绝对可能用于 RIP 相对寻址模式无法进行微熔断的情况,例如 cmpl $1, foo
    【解决方案2】:

    请注意,symbol_name(%rip) 计算从这里到达symbol_name 所需的偏移量,而不是将symbol_name 的绝对地址作为偏移量添加到 RIP。

    但是是的,对于像mov 4(%rip), %rax 这样的数字 偏移量,它将从该指令结束后的 4 个字节开始加载 8 个字节。

    【讨论】:

    • @BingBang:是的,当然可以,如果您的代码位于可写+可执行的页面中。一直如此。这并不意味着您应该,SMC 性能在现代 x86 上非常糟糕。 (每次检测到存储到已经在管道中的地址时,管道核弹。)因此您可以 JIT 一次并运行多次。对于相对于 RIP 的小位移,没有短格式 RIP+rel8 编码,只有 rel32,因此将数据保存在代码旁边也没有任何好处。 (除非您可能会从代码获取中获得 L2 缓存命中,从而将其放入统一的缓存级别。)
    • 我过去一直用 8 位计算机和 C/PM 来做这件事……那是时代!!! :)
    • 请参阅How do RIP-relative variable references like "[RIP + _a]" in x86-64 GAS Intel-syntax work?,了解有关 AT&T 和 Intel 模式下语法的更多详细信息。
    猜你喜欢
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2012-10-19
    • 2012-08-03
    相关资源
    最近更新 更多