Неопределенная ссылка на 'esp' - PullRequest
0 голосов
/ 19 мая 2019

Я получил неопределенную ссылку на '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

Чего я не понимаю, так это того, что esp - это не переменная или функция, а только имя регистра, и, следовательно, не должно приводить к возникновению неопределенной ошибки ссылки.

Почему это происходит и как я могу это исправить?

1 Ответ

5 голосов
/ 19 мая 2019

Проблема вызвана этой строкой:

addl    $4, esp

В других местах регистры задаются с помощью декоратора %, как того требует синтаксис AT & T (например, %esp).

Весь смысл этого декоратора состоит в том, чтобы отличать имена регистров от имен символов - недекорированный esp является символом , а не регистром, как if_digit.

Этообъясняет, почему компоновщик пытается найти что-то под названием esp (и терпит неудачу).Именно поэтому ваше сообщение об ошибке Undefined reference to 'esp', в отличие от '%esp'.


Требование декораторов для имен регистров означает, что источник asm защищен от введения новых имен регистров.Например, если у вас была глобальная переменная с именем xmm0 до приобретения SSE, ваш код не сломался бы с более поздней версией ассемблера, включающей поддержку SSE.

...