对 'esp' 的未定义引用

Undefined reference to 'esp'

我在链接我的目标文件时得到了对 'esp' 的未定义引用。

我在名为 mydc.s

的文件中编写了我的汇编代码

然后我使用

创建了目标文件

as --32 -march=i386 mydc.s -o mydc.o

(这里没有报错) 然后将它链接到

gcc -m32 -march=i386 mydc.o -o mydc

然后它创建了错误消息

(.text+0x2a):对 'esp'

的未定义引用

代码如下

    .section ".text"


    .globl  main
    .type   main,@function

main:

    pushl   %ebp
    movl    %esp, %ebp


input:

    pushl   $buffer 
    pushl   $scanfFormat
    call    scanf
    addl    , %esp

    ## check if user input EOF
    cmp $EOF, %eax
    je  quit

    pushl   $buffer
    call    isdigit
    addl    , esp
    cmp , %eax
    je  if_digit

    movl    buffer, %eax

    cmpl    $'p', %eax
    je  if_p

    cmpl    $'q', %eax
    je  if_q

    cmpl    $'+', %eax
    je  if_plus

if_p:
    movl    iIndex, %eax
    sall    , %eax
    addl    $stack, %eax
    pushl   %eax
    pushl   $resultFormat
    call    printf
    addl    , %esp
    jmp input

我不明白的是 esp 不是变量或函数,只是一个寄存器名称,因此不应产生未定义引用错误。

为什么会发生这种情况,我该如何解决?

问题是由这一行引起的:

addl    , esp

在其他任何地方,您都可以根据 AT&T 语法的要求(例如 %esp)使用 % 装饰器指定寄存器。

这个装饰器的全部意义在于区分寄存器名称和符号名称 - 未装饰的 esp 是一个 符号 而不是一个寄存器,就像 [=14] =].

这解释了为什么链接器试图找到名为 esp 的东西(但失败了)。这也是为什么您的错误消息是 Undefined reference to 'esp',而不是 '%esp'


要求对寄存器名称进行修饰意味着 asm 源 future-proof 反对引入新的寄存器名称。例如,如果在 SSE 被购买之前你有一个名为 xmm0 的全局变量,你的代码将不会与包含 SSE 支持的更高版本的汇编器一起中断。