我想得到这些命令:
jl some_label(%rip) # or jl *%rax
在我为Intel x64架构编写的asm程序中。当我试图编译这段代码时,GCC说“jl的操作数类型不匹配”。
xtfmy6hx1#
条件跳转在x86上是相对的。你可以使用一个“反向”条件跳转,然后是一个无条件跳转:
jge skip_jump jmp *%rax # AT&T syntax skip_jump:
等效的NASM语法是jmp rax。无论哪种方式,它都会设置RIP = RAX,因此这是一个寄存器间接跳转。
jmp rax
7dl7o3gd2#
通常情况下,跳过间接的jmp rax是正确的方法。另一种选择是使用cmov来修改目标地址:
cmov
## Normally worse than jge, but worth considering lea stay_here(%rip), %rdx # pick any register cmovge %rdx, %rax jmp *%rax stay_here:
这是更大的代码大小和更多的uop,但在所采用的路径上总共只有一个分支。此外,间接分支目标的默认预测通常为+0(即下一条指令),因此在预测器是冷的情况下,它可以正确地预测。除此之外,跳转到下一条指令并不是特殊情况,仍然需要正确的预测,并且仍然可能会减慢前端的速度。在一些具有简单/弱间接分支预测的CPU上,将条件合并到间接分支中几乎肯定会受到损害,因为它是一个额外的可能的分支目标。
+0
**但是如果你发现jge/jmp组合不能很好地预测,这将是一种值得尝试的混合方式。
jge
jmp
2条答案
按热度按时间xtfmy6hx1#
条件跳转在x86上是相对的。你可以使用一个“反向”条件跳转,然后是一个无条件跳转:
等效的NASM语法是
jmp rax
。无论哪种方式,它都会设置RIP = RAX,因此这是一个寄存器间接跳转。7dl7o3gd2#
通常情况下,跳过间接的
jmp rax
是正确的方法。另一种选择是使用
cmov
来修改目标地址:这是更大的代码大小和更多的uop,但在所采用的路径上总共只有一个分支。此外,间接分支目标的默认预测通常为
+0
(即下一条指令),因此在预测器是冷的情况下,它可以正确地预测。除此之外,跳转到下一条指令并不是特殊情况,仍然需要正确的预测,并且仍然可能会减慢前端的速度。
在一些具有简单/弱间接分支预测的CPU上,将条件合并到间接分支中几乎肯定会受到损害,因为它是一个额外的可能的分支目标。
**但是如果你发现
jge
/jmp
组合不能很好地预测,这将是一种值得尝试的混合方式。