1

我正在尝试在我的现代机器上编译一个旧项目。我知道这个旧项目使用了旧 (2.x) 版本的 GCC/GAS,所以我需要清理它,以便可以使用当前版本编译它。

有问题的代码:

__get_flags:
    pushfl
    popl %eax
    ret

gas抱怨这pushfl不是一个指令。从我读到的内容来看,这是一个已弃用的旧 GNU 助记符,但肯定有某种 x86_64 等价物吗?

除了回答如何将此代码转换为 x86_64 气体之外,如果有人能解释助记符喜欢和定义和记录的位置,那就太好pushflpushfq。我很确定那是 GAS 的创造物……

注意:我想在 gcc 4.6.1 和 gas 2.21 上编译它

4

2 回答 2

2

以下:

static inline u16 __get_flags(void) {
    u16 flags;
    asm ("pushf\n\t"
         "pop %0" : : "+r"(flags) : "cc");
    return flags;
}

实际上应该对于 64/32 位、x64/x86都是可移植的。但它只为您提供条件代码,而不是状态寄存器的高位部分。如果在 64 位(长)模式下运行时需要标志寄存器的全部内容,请使用PUSHFQ指令名称和u64(或其他 64 位数量)操作数。

于 2011-07-26T16:07:05.383 回答
0

我无法对答案添加评论,因为我没有 50 名声望。反正:

在答案中:

"pop %0" : : "+r"(flags) : "cc");

应该读:

"pop %0" : "=r"(flags) : : "cc");

因为语法是asm( code : outputs : inputs : clobbers )并且您想要的是 flags 是从 asm 块输出的寄存器,而不是用作输入。(我对此进行了测试,它对我有用,我也使用了 64 位整数)

于 2014-11-27T04:43:36.873 回答