“mov offset(%rip), %rax”是什么意思?

11

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

2个回答

13
下一步。这是x86的一般规则(也请参阅分支)。
在英特尔手册卷2第2.2.1.6节中有关RIP相对寻址的内容:

在64位模式下实现了一种新的寻址形式,即RIP相对(相对指令指针)寻址。通过将64位RIP和下一条指令的位移相加来形成有效地址。


1
x86 中的几乎所有内容都是这样工作的。例如,jmp 指令的立即数是相对于下一条指令的位移量。 - Jonathon Reinhart
有趣——但是RIP相对寻址实际上有什么用处? - Alex D
全局变量,换句话说?但是为什么要使用相对于RIP的地址来访问全局变量呢?为什么不直接使用常量地址呢? - Alex D
@AlexD 可以工作,但最好将事情(大多数)保持在低于2GB的范围内(否则常量必须是64位),然后您还需要解决dll的重定位问题。 - harold
1
@AlexD: 因为RIP相对寻址模式比32位绝对寻址模式更短。32位模式有2种冗余的编码方式来编码[disp32]。x86-64将非SIB版本重新用作[rip + rel32],同时保留了没有基址或索引的ModRM+SIB编码作为[disp32]。主要是因为disp32绝对地址仅适用于索引静态数组:在x86-64 Linux中不再允许32位绝对地址?。但是32位绝对地址在某些情况下可能会用到,例如当RIP相对寻址模式无法微融合时,如cmpl $1, foo - Peter Cordes
显示剩余3条评论

9
请注意,symbol_name(%rip) 计算从此处到达 symbol_name 所需的偏移量,而不是将绝对地址添加到 RIP 作为偏移量。
但是,对于数字偏移量(如 mov 4(%rip), %rax),它将加载从此指令结束后的第4个字节开始的8个字节。

@BingBang:当然可以,如果你的代码在一个可写和可执行的页面中。就像以前一样。但这并不意味着你应该这样做,现代x86上SMC性能非常差。(每次检测到对已经在流水线中的地址进行存储时,都会发生管道故障。)因此,您可以JIT一次,多次运行。相对于RIP的小位移没有短格式的RIP+rel8编码,只有rel32,因此将数据保留在代码旁边没有任何好处。(除了可能从代码获取带来统一缓存级别的L2缓存命中。) - Peter Cordes
我曾经经常在8位计算机和C/PM上这样做...那些都是美好的日子!!! :) - Bing Bang
请参阅如何在x86-64 GAS Intel语法中使用RIP相对变量引用,例如“[RIP + _a]”?以获取有关AT&T和Intel模式语法的更多详细信息。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接