【问题标题】:Intel asm syntax with GCC: undefined reference带有 GCC 的 Intel asm 语法:未定义的参考
【发布时间】:2016-04-01 14:36:37
【问题描述】:

我正在运行 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&T asm 语法,但我在大学需要 Intel systax。所以问题是,我怎样才能让它工作?

【问题讨论】:

  • 查看 gcc 文档以了解扩展的内联汇编语法。您必须将参数传递给汇编代码;依靠具有特定名称的当地人已经过时了 20 多年。此外,您还应该使用特定的破坏寄存器。

标签: c gcc


【解决方案1】:

两件事:首先,在 Linux 上,您不会在汇编中为 C 符号添加下划线前缀,因此 xyz 而不是 _x_y_z。其次,这三个变量是自动变量。您不能像这样引用自动变量,因为没有为它们创建符号。相反,您需要告诉编译器将这些变量移交给您的程序集。您还需要将寄存器 eaxecx 标记为已损坏,因为您的程序集修改了它们。阅读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&T 语法中插入对寄存器的引用,从而导致编译错误。更好的是,如果您打算为 gcc 编写大量内联汇编,请学习 AT&T 语法。

【讨论】:

  • 工作!非常感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 2021-10-18
  • 2013-01-16
  • 1970-01-01
  • 2016-02-02
  • 2014-02-13
  • 2014-03-25
相关资源
最近更新 更多