Undefined reference to 'esp'

Jim*_*Suh 0 x86 assembly gnu-assembler att

链接目标文件时,我得到了对“ 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    $8, %esp

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

    pushl   $buffer
    call    isdigit
    addl    $4, esp
    cmp $1, %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    $2, %eax
    addl    $stack, %eax
    pushl   %eax
    pushl   $resultFormat
    call    printf
    addl    $8, %esp
    jmp input
Run Code Online (Sandbox Code Playgroud)

我没有得到的是esp不是变量或函数,只是寄存器名,因此不应创建未定义的引用错误。

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

pax*_*blo 5

问题是由以下行引起的:

addl    $4, esp
Run Code Online (Sandbox Code Playgroud)

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

装饰器的全部目的是将寄存器名称与符号名称区分开-未修饰的esp符号而不是寄存器,就像if_digit

这就解释了链接器为何要查找称为esp(失败)的内容的原因。这也是为什么您的错误消息Undefined reference to 'esp'与相对的原因'%esp'


要求在寄存器名称上使用修饰符意味着,asm源代码可以防止将来引入新的寄存器名称。例如,如果xmm0在购买SSE之前有一个全局变量被调用,那么您的代码将不会与包含SSE支持的更高版本的汇编程序版本一起使用。