I got undefined reference to 'esp', while linking my object file.
I wrote my assembly code in file named mydc.s
Then I created object file using
as --32 -march=i386 mydc.s -o mydc.o
(There was no error here) Then linked it with
gcc -m32 -march=i386 mydc.o -o mydc
Then it created error message as
(.text+0x2a): undefined reference to 'esp'
The code is as following
.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
What I don't get is that esp is not a variable or function, just a register name, and thus should not create no undefined reference error.
Why does this happen, and how can I fix this?
The problem is caused by this line:
addl $4, esp
Everywhere else, you specify registers with the %
decorator, as required by AT&T syntax (%esp
, for example).
The whole point of this decorator is to distinguish register names from symbol names - the undecorated esp
is a symbol rather then a register, just like if_digit
.
This explains why the linker is trying to find something called esp
(and failing). It's also why your error message is Undefined reference to 'esp'
, as opposed to '%esp'
.
Requiring decorators on register names means that asm source is future-proof against introduction of new register names. For example if you had a global variable called xmm0
before SSE was bought into existence, your code wouldn't break with a later assembler version that included SSE support.