assembly 条件跳转到寄存器

wpx232ag  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(103)

我想得到这些命令:

jl some_label(%rip)
# or
jl *%rax

在我为Intel x64架构编写的asm程序中。
当我试图编译这段代码时,GCC说“jl的操作数类型不匹配”。

xtfmy6hx

xtfmy6hx1#

条件跳转在x86上是相对的。你可以使用一个“反向”条件跳转,然后是一个无条件跳转:

jge   skip_jump
  jmp   *%rax       # AT&T syntax
skip_jump:

等效的NASM语法是jmp rax。无论哪种方式,它都会设置RIP = RAX,因此这是一个寄存器间接跳转。

7dl7o3gd

7dl7o3gd2#

通常情况下,跳过间接的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:

这是更大的代码大小和更多的uop,但在所采用的路径上总共只有一个分支。此外,间接分支目标的默认预测通常为+0(即下一条指令),因此在预测器是冷的情况下,它可以正确地预测。
除此之外,跳转到下一条指令并不是特殊情况,仍然需要正确的预测,并且仍然可能会减慢前端的速度。
在一些具有简单/弱间接分支预测的CPU上,将条件合并到间接分支中几乎肯定会受到损害,因为它是一个额外的可能的分支目标。

**但是如果你发现jge/jmp组合不能很好地预测,这将是一种值得尝试的混合方式。

相关问题