【发布时间】:2016-03-26 10:07:00
【问题描述】:
使用 GCC 中的内联汇编,您可以使用 "i" 约束指定直接 asm 操作数,如下所示:
void set_to_five(int* p)
{
asm
(
"movl %1, (%0);"
:: "r" (p)
, "i" (5)
);
}
int main()
{
int i;
set_to_five(&i);
assert(i == 5);
}
到目前为止,这并没有什么问题,只是它的 AT&T 语法很糟糕。所以让我们再试一次.intel_syntax noprefix:
void set_to_five(int* p)
{
asm
(
".intel_syntax noprefix;"
"mov [%0], %1;"
".att_syntax prefix;"
:: "r" (p)
, "i" (5)
);
}
但这不起作用,因为编译器在立即数之前插入了一个 $ 前缀,汇编器不再理解。
如何在 Intel 语法中使用 "i" 约束?
【问题讨论】:
-
尝试使用
%c1(参见gcc.gnu.org/onlinedocs/gcc/…)。此外,请考虑使用 -masm=intel 而不是伪操作。 -
我一定已经阅读了该页面 10 次,但不知何故我错过了那一点。谢谢!您应该将此作为答案发布。
-
尽管我很想使用
-masm=intel,但在包含带有 AT&T 语法 asm 的标头时会引起麻烦。 -
您正在使用哪些包含内联 asm 的标头?正是出于这个原因,公共标头应该使用方言(请参阅gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#AssemblerTemplate 下的“asm 模板中的多个汇编程序方言”)。但当然不是每个人都这样做。
-
djgpp 标准库有其中一些......但我现在想我可以用英特尔语法重新实现它们。或者使用像
INTEL_ASM_BEGIN/INTEL_ASM_END这样的宏,并根据使用的-masm设置将它们定义为相应的伪操作或不定义任何内容。我不喜欢多方言功能,代码重复是一件坏事:)
标签: gcc inline-assembly