簡體   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