I want to get these commands:
jl some_label(%rip)
# or
jl *%rax
in my asm program that I am writing for Intel x64 architecture.
GCC says that "operand type mismatch for jl" when I try to compile this code.
条件跳转在 x86 上是相对的。您可以使用“反向”条件跳转,然后是无条件跳转:
jge skip_jump
jmp *%rax # AT&T syntax
skip_jump:
等效的 NASM 语法是jmp rax
. 无论哪种方式,它都设置 RIP = RAX,所以它是寄存器间接跳转。
有条件地跳过间接jmp rax
的通常是要走的路。
另一种选择是用来cmov
修改目标地址:
## Normally worse than jge, but worth considering
lea stay_here(%rip), %rdx # pick any register
cmovge %rdx, %rax
jmp *%rax
stay_here:
这是更大的代码大小和更多的微指令,但在所采用的路径上只有一个总分支。+0
此外,如果 BTB 没有历史记录,则间接分支目标的默认预测通常是(即下一条指令),因此在预测器很冷的情况下它可以正确预测。
除此之外,跳转到下一条指令并不是特殊情况,仍然需要正确的预测,并且仍然可能会减慢前端的速度。
在一些具有简单/弱间接分支预测的 CPU 上,将条件合并到间接分支中几乎肯定会受到伤害,因为它是一个额外的可能分支目标。
但是,如果您发现jge
/jmp
组合的预测效果不佳,那么值得尝试将其作为一种混合方式。