实验是在32-bit
x86
Linux 上进行的。
我正在做一些静态二进制检测工作,基本上我试图在每个基本块的开头插入一些指令。
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 带来的太多性能损失。有什么办法可以避免高开销并保持正确的语义?(保护标志中的值,基本上......)
我够清楚了吗?谁能给我一些帮助?