条件跳转到内存地址
像下面这样的事情可能吗?
cmp $3, %rdi
jz (%r11)
file.s:52: 错误:`jz' 的操作数类型不匹配
或者:
警告:不带 `*' 的间接 jmp
或者您是否必须“跳过”一个标签,然后才能执行jmp %r11. 或者它是如何工作的?
似乎这里至少发生了一些事情,但其中之一是:
- 除非我更改
jmp %r11为jmp *%r11(为什么?),否则发出警告
目前我正在做的是回旋处:
cmp $3, %rdi
jz fast_ret
fast_ret:
jmp *%r11
回答
不,x86 上的所有条件跳转指令都是立即的;它们将目标地址直接编码到指令中(作为跳转指令本身地址的位移)。您不能有条件地从寄存器或内存位置跳转到地址。
你可以做你所做的,并跳转到所需的跳转指令。或者您可以反向测试并跳过您真正想要的寄存器或间接跳转。
cmp $3, %rdi
jnz dont_go
jmp *%r11
dont_go:
// rest of your program
您的方式的优点是在“不相等”的情况下不进行跳转,尽管现代处理器上的分支预测不应在“已采用”和“未采用”之间留下太大差异。我的方法的优点是,两种情况都不涉及两次跳转,并且不会跳转到缓存中可能很冷的某个相对较远的中间地址。
请注意以下之间的区别:
-
jmp %r11:AT&T 的无效语法,绝对跳转总是带*前缀,请参阅https://sourceware.org/binutils/docs/as/i386_002dVariations.html#i386_002dVariations。 -
jmp *%r11: 使用 的内容%r11作为跳转的地址。你可以把它想象成做mov %r11, %rip。 -
jmp *(%r11): 间接跳转,从%r11包含的地址中取出目的地址。你可以把它想象成做mov (%r11), %rip。