我知道何时使用补鞋匠列表(例如列出在程序集中修改的寄存器,以便它不被选择用作输入寄存器等),但我无法绕过早期约束条件&.如果列出输出,那是否已经意味着输入不能使用所选寄存器(除了匹配数字约束)?
例如:
asm(
"movl $1, %0;"
"addl $3, %0;"
"addl $4, %1;"
"addl %1, %0;"
: "=g"(num_out)
: "g"(num_in)
:
);
Run Code Online (Sandbox Code Playgroud)
会&甚至需要为输出变量?编译器应该知道为输出选择的寄存器,因此知道不要将它用于输入.
我正在尝试将历史功能语言解释器(EMAS的KRC)移植到现代系统(C for Unix),并且它有一个垃圾收集器,希望能够扫描堆栈以获取指向堆的指针,以了解它必须重新定位哪些指针在GC期间移动堆中的对象时.为此,必须在堆栈中找到指向堆的所有函数参数和局部变量.
现在,有一段时间"注册"关键字意味着"如果你愿意,你可以把这个变量放在寄存器中",否则它就在堆栈上,但现在所有(GCC,Clang,Tinyc/tcc)C编译器似乎无论如何都将局部变量放入寄存器中,无法禁用此行为,结果是GC错过了属于正在进行的函数的某些值,无法保留它们并破坏堆.
有没有办法告诉任何这些编译器使用原始的C语义,除非你说"注册",否则所有局部变量都在堆栈中?
我有一些狡猾的"解决方案":
这似乎都改善了问题,但是非常黑客和不可靠.
是否有更好的方法来实现所需的结果,确保所有函数参数和局部变量都在堆栈中?
我已经看过这个问题,但由于以下原因,这两个解决方案都不适合我.
是否有可能以某种方式包装一组c ++语句来告诉编译器不使用某些寄存器?