如何在AT&T语法中对标签进行相对jmp?



如果我在汇编中写(at&t syntax, x86-64):

jmpq 0x4(%rip)

然后跳到4+rip

但它跳如果我写:

jmpq label(%rip)

Where label = 4?

我很困惑,因为它可以是相同的答案或与movq相同,我们移动标签和NOT标签+ rip.

要执行正常的相对跳转,导致RIP = label,使用jmp label.
汇编程序计算相对位移

(是的,您必须使用jmp而不是jmpqjmp的操作数大小后缀意味着AT&T语法的间接跳转,不像calll/callq,这是一个疯狂和令人困惑的糟糕设计。

相对直接跳转的工作方式与8086以来相同,并且与x86-64中新的rip相对数据寻址模式没有任何关系。(像"[RIP + _a]"在x86-64 GAS英特尔语法工作?还介绍了AT&T语法如何用于4(%rip)label(%rip)的数据寻址。)

如果不想从函数指针加载新的RIP,那么不要使用内存寻址模式。相对jmp不能访问内存本身;label的内存只有在jmp完成后才能被代码获取访问。(真正的cpu是流水线的分支预测和东西,但仍然保持幻觉指令完全执行前一个开始,例如一个相对的jmp到一个未映射的页面可以完全执行没有自己的错误,只有下一个代码提取操作错误与保存的RIP =新的位置。)

然后jmpq 0x4(%rip)跳到4+rip

不,没有。如果你真的组装了它,它会警告indirect jmp without '*'。拆卸显示

ff 25 04 00 00 00       jmp    *0x4(%rip)

。它从内存中加载一个指针到RIP中,从jmp指令结束后4个字节开始的qword中。它没有设置RIP = RIP+4,那将是jmp .+2 + 4(因为短跳是2字节长,或者如果你在jmp后面放一个标签,jmp end_of_insn + 4)

最新更新