我正在运行Ubuntu 64位,我有这段代码:
#include <stdio.h>
int main() {
int x, y;
int z = 0;
printf("Enter two numbers: ");
scanf("%d %d", &x, &y);
asm(".intel_syntax noprefix\n"
"MOV EAX, _x\n"
"MOV ECX, _y\n"
"ADD EAX, ECX\n"
"MOV _z, EAX\n"
".att_syntax\n");
printf("%d + %d = %d \n", x, y, z);
return 0;
}
根据在学校的讲座,它应该可以工作,但是当我尝试用GCC编译它时,我得到了这个错误:
/tmp/ccU4vNLr.o: In function `main':
Jung_79913_211.c:(.text+0x4a): undefined reference to `_x'
Jung_79913_211.c:(.text+0x51): undefined reference to `_y'
Jung_79913_211.c:(.text+0x5a): undefined reference to `_z'
collect2: error: ld returned 1 exit status
我知道GCC默认使用AT&amp; T asm语法,但我需要在大学使用英特尔systax。所以问题是,我怎么能让它发挥作用?
答案 0 :(得分:3)
两件事:首先,在Linux上,您不要在汇编中使用下划线为C符号添加前缀,因此x
,y
,z
代替_x
,_y
,_z
。其次,这三个变量是自动变量。您不能像这样引用自动变量,因为没有为它们创建符号。相反,您需要告诉编译器将这些变量移交到程序集中。您还需要将寄存器eax
和ecx
标记为已破坏,因为您的程序集会修改它们。有关详细信息,请阅读this documentation。以下是如何使用您的代码:
asm(
"MOV EAX, %1\n"
"MOV ECX, %2\n"
"ADD EAX, ECX\n"
"MOV %0, EAX\n"
: "=r" (z) : "r" (x), "r" (y) : "eax", "ecx");
您还需要使用-masm=intel
进行编译才能正常工作,否则gcc将在AT&amp; T语法中插入对寄存器的引用,从而导致编译错误。更好的是,如果您计划为gcc编写大量内联汇编,请学习AT&amp; T语法。