gpt4 book ai didi

GCC 内联汇编错误 : Error: junk `(%esp)' after expression

转载 作者:行者123 更新时间:2023-12-04 03:02:40 24 4
gpt4 key购买 nike

GCC 内联汇编错误:错误:表达式后出现垃圾 `(%esp)'

我正在研究 gcc 内联汇编。我的环境是Win 7 32bit,mingw-gcc 4.6.1。

我对“m”约束有疑问。这是我的 C 函数代码:

static int asm_test(int a, int b)
{

int c = 0;
__asm__ __volatile__(".intel_syntax\n"
"mov eax, %1\n" //error
"mov edx, %2\n" //error
"add eax, edx\n"
"mov %0, eax\n" //error
".att_syntax"
:"=m"(c)\
:"m"(a),"m"(b)\
:"eax","edx"
);
return c;
}

对于at&t代码,是这样的:

static int asm_test(int a, int b)
{

int c = 0;
__asm__ __volatile__(
"movl %1, $eax\n" //error
"movl %2, $edx\n" //error
"addl $edx, $eax\n"
"movl $eax, %0\n" //error
:"=m"(c)\
:"m"(a),"m"(b)\
:"eax","edx"
);
return c;
}

对于操作输入/输出操作数的三行,gcc在编译时都会报错,如下所示:

C:\Users\farta\AppData\Local\Temp\cc99HxYj.s:22: 错误:表达式后出现垃圾 `(%esp)'

如果我使用“r”作为输入/输出约束,代码将起作用。但我不明白它为什么有效以及错误代表什么。谁能告诉我?据我所知,如果内联汇编代码试图访问输入/输出操作数,“m”只是告诉 gcc 不要分配寄存器,而是直接在内存中访问它们。这是正确的吗?

非常感谢。

最佳答案

这里的问题是 GCC 为 %0%1%2 生成 AT&T 语法结构。如果您查看生成的程序集,它看起来像:

.intel_syntax
mov eax, 8(%ebp)
mov edx, 12(%ebp)
add eax, edx
mov -4(%ebp), eax

这不是有效的英特尔语法。

通常,您不需要在内联汇编中包含显式加载/存储操作 - 只需指定寄存器约束,编译器将自行生成加载/存储。这样做的好处是,即使您的变量(参数、局部变量)根本不驻留在内存中,而是在寄存器中,您的代码仍然是正确的——这与您显式将内存加载/存储放在那里的情况不同。

对于您的示例,请尝试以下代码,查看程序集 (gcc -S) 并注意编译器如何自行从参数区域(例如 x86 上的堆栈)执行移动。

int asm_test(int a, int b)
{
__asm__ __volatile__ (
".intel_syntax\n"
"add %0, %1 \n"
".att_syntax \n"
:"+r"(a)
:"r"(b));
return a;

关于GCC 内联汇编错误 : Error: junk `(%esp)' after expression,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13856792/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com