【发布时间】:2014-11-15 03:05:34
【问题描述】:
我正在尝试通过 x86 mul 指令执行 64=32x32 乘法,但我只需要结果的高位双字(edx 寄存器)。所以很自然地,我尝试将edx 列为输出寄存器,将eax 列为被破坏的寄存器。
这对我来说似乎很自然,但eax 也是一个输入寄存器。当我试图告诉 GCC eax 已被破坏时,它会给出一条错误消息。
__asm__("mull\t%2" : "=d"(div10) : "%a"(UINT32_C(0x1999999A)), "r"(number)
: "cc", "rax");
如果我尝试这样做,它会抛出以下错误消息:
divmod10.cpp:76:91: error: can’t find a register in class ‘AREG’ while reloading
‘asm’
divmod10.cpp:76:91: error: ‘asm’ operand has impossible constraints
省略它会编译,但会破坏代码。 GCC 最终依赖于 eax 未被破坏,这是不正确的:
movl $429496730, %eax
#APP
# 76 "divmod10.cpp" 1
mull %esi
# 0 "" 2
#NO_APP
movl %edx, %esi
#APP
# 78 "divmod10.cpp" 1
mull %edx
# 0 "" 2
#NO_APP
我该如何做我想做的事?
【问题讨论】:
-
来自文档 (gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html):
It is not possible to use Clobbers to inform the compiler that the values in these inputs are changing.使用垃圾变量作为输出:__asm__("mull\t%2" : "=d"(div10), "=a"(junk) : "1"(UINT32_C(0x1999999A)), "r"(number) : "cc");。
标签: c gcc x86 inline-assembly