实验是在32-bit x86Linux 上进行的。
我正在做一些静态二进制检测工作,基本上我试图在每个基本块的开头插入一些指令。
BB23 : push %eax
movl index,%eax
movl $0x80823d0,buf(,%eax,0x4)
add $0x1,%eax
cmp $0x400000,%eax
jle BB_23_stub
movl $0x0,%eax
BB_23_stub:movl %eax,index
pop %eax
注意我需要使用cmp指令,并且为了保证flags可以恢复到原始值,我使用pushf并在堆栈上popf存储\加载flags。
然后就变成这样了:
BB_23 : push %eax
pushf
movl index,%eax
movl $0x17,buf(,%eax,0x4)
add $0x1,%eax
cmp $0x400000,%eax
jle BB_23_stub
movl $0x0,%eax
BB_23_stub:movl %eax,index
popf
pop %eax
我测试了有和没有pushf和的性能popf(我正在使用gzip和bzip)。令我惊讶的是,使用pushf和popf说明后,性能损失甚至可能增加 3 倍!!
但是,没有pushf和popf。的压缩结果gzip和bzip不正确。
所以这是我的问题:
为什么 pushf 和 popf 这么慢?我是否以正确的方式使用它?
我无法承受 pushf 和 popf 带来的太多性能损失。有什么办法可以避免高开销并保持正确的语义?(保护标志中的值,基本上......)
我够清楚了吗?谁能给我一些帮助?