这是一个奇怪的要求,但我觉得它有可能.我想要的是将一些编译指示或指令插入到我的代码区域(用C编写),以便GCC的寄存器分配器不会使用它们.
我知道我可以做这样的事情,这可能会为这个变量留下这个寄存器
register int var1 asm ("EBX") = 1984;
register int var2 asm ("r9") = 101;
Run Code Online (Sandbox Code Playgroud)
问题是我直接插入新指令(用于硬件模拟器),而GCC和GAS还没有识别出这些指令.我的新指令可以使用现有的通用寄存器,我想确保我保留了一些(即r12-> r15).
现在,我在一个模拟环境中工作,我想快速做我的实验.将来我会添加GAS并将内在函数添加到GCC中,但是现在我正在寻找快速修复.
谢谢!
以下摘自GCC 手册的 Extended Asm docs,关于使用asm关键字在 C 中嵌入汇编指令:
如果一个输出参数 ( a ) 允许寄存器约束而另一个输出参数 ( b ) 允许内存约束,则会出现同样的问题。GCC 生成的用于访问b 中的内存地址的代码 可以包含可能由a共享的寄存器,并且 GCC 将这些寄存器视为 asm 的输入。如上所述,GCC 假设在写入任何输出之前消耗此类输入寄存器。如果 asm 语句在使用 b 之前写入 a,则此假设可能会导致不正确的行为。与对寄存器约束结合“&”改性剂一确保修改一个不影响通过引用的地址b. 否则,位置b,如果未定义 一个使用之前改性b。
斜体句子表示如果 asm 语句a在使用b.
我无法弄清楚这种“不正确的行为”是如何发生的,所以我希望有一个具体的 asm 代码示例来演示“不正确的行为”,以便我可以深入理解这一段。
当两个这样的 asm 代码并行运行时,我可以察觉到问题,但上面的段落没有提到多处理场景。
如果我们只有一个单核的CPU,能否请您出示一个asm代码,可能会产生这样的错误行为,即修改a影响引用的地址,b使得其位置b未定义。
我唯一熟悉的汇编语言是 Intel x86 汇编,因此请让示例针对该平台。
在我的计算机上,编译的可执行文件省略了在循环顶部执行"mov%2,%% ax"
当"添加%1,%% ax"取消注释时.
有人要进行双重检查或评论?
#include <stdio.h>
int main() {
short unsigned result, low ,high;
low = 0;
high = 1;
__asm__ (
"movl $10, %%ecx \n\t"
"loop: mov %2, %%ax \n\t"
// "add %1, %%ax \n\t" // uncomment and result = 10
"mov %%ax, %0 \n\t"
"subl $1, %%ecx \n\t"
"jnz loop"
: "=r" (result)
: "r" (low) , "r" (high)
: "%ecx" ,"%eax" );
printf("%d\n", result);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
跟随生成的程序集
movl $1, %esi
xorl %edx, %edx
/APP
movl …Run Code Online (Sandbox Code Playgroud)