繁体   English   中英

GCC 编译为程序集:cmp 后跟调用而不是条件跳转

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM