相关疑难解决方法(0)

何时在扩展GCC内联汇编中使用earlyclobber约束?

我知道何时使用补鞋匠列表(例如列出在程序集中修改的寄存器,以便它不被选择用作输入寄存器等),但我无法绕过早期约束条件&.如果列出输出,那是否已经意味着输入不能使用所选寄存器(除了匹配数字约束)?

例如:

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)

&甚至需要为输出变量?编译器应该知道为输出选择的寄存器,因此知道不要将它用于输入.

c assembly gcc inline-assembly

9
推荐指数
2
解决办法
1913
查看次数

如何坚持C编译器将局部变量放在堆栈上,而不是寄存器中

我正在尝试将历史功能语言解释器(EMAS的KRC)移植到现代系统(C for Unix),并且它有一个垃圾收集器,希望能够扫描堆栈以获取指向堆的指针,以了解它必须重新定位哪些指针在GC期间移动堆中的对象时.为此,必须在堆栈中找到指向堆的所有函数参数和局部变量.

现在,有一段时间"注册"关键字意味着"如果你愿意,你可以把这个变量放在寄存器中",否则它就在堆栈上,但现在所有(GCC,Clang,Tinyc/tcc)C编译器似乎无论如何都将局部变量放入寄存器中,无法禁用此行为,结果是GC错过了属于正在进行的函数的某些值,无法保留它们并破坏堆.

有没有办法告诉任何这些编译器使用原始的C语义,除非你说"注册",否则所有局部变量都在堆栈中?

我有一些狡猾的"解决方案":

  • 在任何地方添加额外的代码来获取每个面向堆的局部变量的地址并将其传递给虚函数,作为强制它在内存位置的一种方式;
  • 使所有静态函数全局化,以避免函数内联以及内联函数参数的优化输出;
  • 将GC()函数括在一个存根中,该存根将所有机器寄存器压入堆栈,调用真正的GC()函数然后弹出它们;

这似乎都改善了问题,但是非常黑客和不可靠.

是否有更好的方法来实现所需的结果,确保所有函数参数和局部变量都在堆栈中?

c gcc garbage-collection clang tcc

6
推荐指数
1
解决办法
1425
查看次数

是否可以禁止在一小段C++代码中使用某些寄存器?

我已经看过这个问题,但由于以下原因,这两个解决方案都不适合我.

  1. 我试图阻止c ++代码接触寄存器,而不是汇编,因此clobber列表将无法工作.
  2. 我想在本地执行此操作,而不是全局执行此操作,因此全局显式寄存器变量过于严厉.

是否有可能以某种方式包装一组c ++语句来告诉编译器不使用某些寄存器?

c++ g++

6
推荐指数
1
解决办法
148
查看次数

标签 统计

c ×2

gcc ×2

assembly ×1

c++ ×1

clang ×1

g++ ×1

garbage-collection ×1

inline-assembly ×1

tcc ×1