我怎么告诉GCC汇编,一个输入寄存器被打一顿? [英] How do I tell GCC asm that an input register is clobbered?

查看:197
本文介绍了我怎么告诉GCC汇编,一个输入寄存器被打一顿?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个64 = 32x32乘法通过86 MUL 指示,但我只需要结果的高DWORD(即 EDX 报名)。所以很自然,我想上市的 EDX 作为输出寄存器和 EAX 作为修饰寄存器。

I'm trying to do a 64=32x32 multiply via the x86 mul instruction, but I only need the high dword of the result (the edx register). So naturally, I tried listing edx as an output register and eax as a clobbered register.

这似乎很自然的我,但 EAX 的输入寄存器。当我试着告诉GCC的 EAX 被破坏的,它提供了一个错误信息。

This seems natural to me, but eax is also an input register. When I try to tell GCC that eax is clobbered, it gives an error message.

__asm__("mull\t%2" : "=d"(div10) : "%a"(UINT32_C(0x1999999A)), "r"(number)
    : "cc", "rax");

如果我尝试,它抛出此错误消息:

If I try that, it throws this error message:

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

忽略它编译,但打破了code。 GCC最终依赖于 EAX 未被破坏的,这是不正确的:

Omitting it compiles, but breaks the code. GCC ends up relying upon eax not being clobbered, which is incorrect:

        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

我怎么做我想要什么?

How do I do what I want?

推荐答案

只要为输出进入,编译器将优化出来一个无用的温度。例如:

Just make a useless temp for the output to go into and the compiler will optimize it out. For example:

__asm__("mull\t%2" : "=d"(div10), "=a"((int){0})
    : "a"(UINT32_C(0x1999999A)), "r"(number) : "cc");

这是我所知道的处理被破坏输入的最简单的方法。

That's the easiest way I know to handle clobbered inputs.

这篇关于我怎么告诉GCC汇编,一个输入寄存器被打一顿?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆