我正在尝试在现代机器上编译旧项目。我知道这个旧项目使用了旧的(2.x)版本的GCC / GAS,所以我需要清理它以便我可以用当前版本编译它。
有问题的代码:
__get_flags:
pushfl
popl %eax
ret
gas
抱怨pushfl
不是指令。从我读到的这是一个旧的弃用的GNU助记符,但必定有某种x86_64等价,当然?
除了回答如何将此代码转换为x86_64气体之外,如果有人能够解释pushfl
和pushfq
等助记符并进行定义和记录,那将会很棒。我很确定这是GAS创作......
注意:我想在gcc 4.6.1和gas 2.21上编译它
答案 0 :(得分:2)
以下内容:
static inline u16 __get_flags(void) {
u16 flags;
asm ("pushf\n\t"
"pop %0" : : "+r"(flags) : "cc");
return flags;
}
对于64 / 32bit,x64 / x86,实际上应该是便携式。但它只能获取条件代码,而不是状态寄存器的高位部分。如果在64位(长)模式下运行时需要标志寄存器的全部内容,请使用PUSHFQ
指令名称,并带有u64
(或其他64位数量)操作数。
答案 1 :(得分:0)
我无法在答案中添加评论,因为我没有50个声望。无论如何:
答案:
"pop %0" : : "+r"(flags) : "cc");
应阅读:
"pop %0" : "=r"(flags) : : "cc");
因为语法是asm( code : outputs : inputs : clobbers )
,你想要的是标志是从asm块输出的寄存器,而不是用作输入。 (我测试了它,它对我有效,我也使用了64位整数)