![](/img/trans.png)
[英]Is it possible to use a conditional jump in assembly without a `cmp` first?
[英]GCC compile to assembly: cmp followed by call instead of conditional jump
这个汇编代码合理吗?
cmp op1, op2
pushf
call _func
popf
jz .L0
我想知道在什么情况下 GCC as可以生成这样的代码,即cmp后跟调用而不是条件跳转
不,GCC 永远不会那样做,它总是会使用setz bl
或其他东西(在调用保留的寄存器中),如果它想现在实现一个布尔值以在调用后使用。 或者只是确保在调用后到cmp
两个 args 都可用,然后执行或重做比较。
这两者中的任何一个都会便宜得多; popf
很慢,因为它可以像 AC 一样修改 FLAGS,并且(在内核模式下)像 IF 一样修改 FLAGS。 它需要取决于 CPU 模式的条件行为。 它被微编码为许多 uops。 (在https://agner.org/optimize/查看说明表)。 像 Skylake-X 上的 7 个,每 21 个周期的吞吐量为 1 个 ( https://uops.info )。
如果人类程序员真的想保存/恢复多个 FLAGS 包括 ZF,他们会使用lahf
/ mov ebx, eax
或其他东西。 我认为 GCC 也不会这样做。
GCC 从不在调用周围使用 push/pop 来保存/恢复某些东西。 它在函数顶部保留空间并保存它想要使用的任何保留调用的寄存器。 要在调用之前将某些内容溢出到内存中,它将使用mov
而不是 push。
GCC 仅在调用之前使用 push 来传递堆栈参数。 但是我们可以排除您的示例(并假设call _func
接受堆栈参数),因为函数拥有它们的堆栈参数。 因此,如果pushf
一直在传递 arg,则popf
将弹出_func
可能踩到的潜在垃圾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.