GCC Intel语法内联汇编报错:invalid operands (.text and UND sections) for + 求助
解决GCC Intel语法内联汇编的编译错误
你的编译错误主要来自两个核心问题:内联汇编操作数的引用格式错误和输入约束的语法错误,另外编译命令也有小问题。下面一步步拆解修复:
错误原因分析
- 操作数引用错误:在GCC的Intel语法内联汇编中,引用输入/输出操作数应该用
%[符号名],而不是你用的$[符号名]。$在Intel语法里是立即数前缀,你这样写会让汇编器把[source]当成一个符号,尝试和文本段地址做加法,导致"invalid operands for+"错误。 - 输入约束语法错误:GCC内联汇编的输入约束格式是
[符号名] "约束字符串" (变量名),你写成了"r" "source" (_source),完全不符合语法,这会让编译器无法正确关联变量和汇编里的符号。 - 编译命令错误:你的命令
gcc -m32 -masm=intel -o test.cpp会把输出文件命名为test.cpp(可能覆盖源文件),正确应该指定可执行文件名,比如test。
修正后的代码
int main() { char* _source = new char [1]; _source[0] = 1; char* array = new char[1]; unsigned int i = 0; __asm volatile ( "mov eax, %[source] \n\t" "add eax, %[i] \n\t" "mov al, [eax] \n\t" // 用al代替bh,更契合字节操作的场景,不影响功能 "mov ecx, %[array] \n\t" "add ecx, %[i] \n\t" "mov [ecx], al \n\t" : // 无输出操作数 : [source] "r" (_source), [array] "r" (array), [i] "r" (i) // 正确的输入约束格式 : "eax", "ecx", "memory" // 移除bh的clobber声明,因为改用了al ); // 释放动态分配的内存,避免泄漏 delete[] _source; delete[] array; return 0; }
关键修复点说明
- 操作数引用修正:把所有
$[xxx]改成%[xxx],这是GCC Intel语法中引用命名操作数的标准方式。 - 输入约束格式修正:调整为
[符号名] "约束" (变量)的正确格式,让编译器能正确绑定C变量和汇编中的符号。 - 寄存器优化:将
bh换成al,al是eax的低8位,和eax配合更自然,同时减少了需要声明为被破坏的寄存器数量。 - 内存管理完善:添加
delete[]释放动态内存,避免内存泄漏问题。 - 编译命令修正:正确的编译命令应为:
gcc -m32 -masm=intel -o test test.cpp
额外建议
如果你的需求只是实现array[i] = _source[i]的功能,其实完全不需要内联汇编,直接用C代码更简洁安全。但如果是学习内联汇编的目的,上面的修正可以完美解决你的编译问题。编写GCC内联汇编时,一定要注意AT&T和Intel语法的差异,尤其是操作数前缀、后缀和约束格式的区别。
内容的提问来源于stack exchange,提问作者Salty 27
相关产品推荐
相关产品推荐

