Myr*_*ria 5 c x86 gcc inline-assembly
我正在尝试通过x86 mul
指令执行64 = 32x32乘法,但是我只需要结果的高双字(edx
寄存器)。因此,很自然地,我尝试将清单edx
作为输出寄存器和eax
破坏寄存器。
这对我来说似乎很自然,但eax
它也是一个输入寄存器。当我尝试告诉GCC eax
被破坏时,它会给出错误消息。
__asm__("mull\t%2" : "=d"(div10) : "%a"(UINT32_C(0x1999999A)), "r"(number)
: "cc", "rax");
Run Code Online (Sandbox Code Playgroud)
如果我尝试这样做,则会引发此错误消息:
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
Run Code Online (Sandbox Code Playgroud)
省略它可以编译,但是会破坏代码。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
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
只需为输出设置一个无用的临时值,编译器就会对其进行优化。例如:
__asm__("mull\t%2" : "=d"(div10), "=a"((int){0})
: "a"(UINT32_C(0x1999999A)), "r"(number) : "cc");
Run Code Online (Sandbox Code Playgroud)
这是我所知道的处理损坏输入的最简单方法。