【发布时间】:2020-04-25 11:18:31
【问题描述】:
我试图在我的部分代码中使用汇编,但我需要使用多个变量。为什么我不能为 C 变量使用两个以上的寄存器?
__asm(
"add %eex, %edx\n"
"add %eax, %ecx\n"
"mov 1 ,%0\n"
:"=r"(side)
:"a"(map.y));
:"e"(sdist.y)
:"d"(delta.y)
:"c"(step.y)
);
当我编译这个时,我得到了错误
a.c: In function ‘main’:
a.c:289:2: error: expected expression before ‘:’ token
:"e"(sdist.y)
^
a.c:292:1: error: expected statement before ‘)’ token
);
【问题讨论】:
-
可能是这一行的尾随分号或额外的括号?
:"a"(map.y)); -
);应该在编译器标记错误的地方吗? -
请注意,这里没有 EEX 寄存器,并且“e”约束并不表示寄存器操作数。
-
这在很多其他方面都非常糟糕,包括语法(多个输入操作数应该用逗号分隔),
1是绝对地址1;也许您的意思是$1立即数或%1操作数?此外,x86 的"e"约束是适合 32 位符号扩展的立即数;没有eex注册。您的其他输入约束都是特定的寄存器。 gcc.gnu.org/onlinedocs/gcc/…。哦,还有,这破坏了只读输入操作数(如 EDX 和 ECX)中的值,违反了约束。 -
TL:DR:请参阅 stackoverflow.com/tags/inline-assembly/info 获取指南和教程的链接。 使用 GNU C 内联 asm 将代码扔到墙上直到它粘住甚至比平时更糟糕:很容易(如果你得到约束甚至是微妙的错误)使代码恰好与一组正确工作周围的代码,但因不同的优化选项或对其他代码的微小更改而中断。在签署一段内联汇编之前,请确保您准确了解所有内容以及为什么它是安全的。或者不要使用它。
标签: c assembly cpu-registers