简体   繁体   中英

GCC compile to assembly: cmp followed by call instead of conditional jump

Is this assembly code reasonable?

cmp op1, op2
pushf
call _func
popf
jz .L0

I am wondering under what circumstances that GCC as can generate such code that cmp is followed by call instead of conditional jump

No, GCC would never do that, it would always use setz bl or something (in a call-preserved register) if it wanted to materialize a boolean now for use after a call. Or just make sure both args to cmp would be available after the call and do or redo the compare then.

Either of these would be much cheaper; popf is quite slow because it can modify FLAGS like AC, and (in kernel mode) FLAGS like IF. It needs conditional behaviour depending on CPU mode. It's microcoded as many uops. (Check instruction tables at https://agner.org/optimize/ ). Like 7 on Skylake-X, with a throughput of one per 21 cycles ( https://uops.info ).

If a human programmer really wanted to save / restore multiple FLAGS including ZF, they'd use lahf / mov ebx, eax or something. I don't think GCC tends to do that either.

GCC never uses push/pop around a call to save/restore something. It reserves space at the top of the function and saves any call-preserved registers it wants to use. To spill something to memory before a call, it would use mov , not push.

GCC only uses push before a call to pass stack args. But we can rule that out for your example (and assume call _func takes no stack args) because functions own their stack args. So if pushf had been passing an arg, popf would be popping potential garbage that _func could have stepped on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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