![](/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.