.quad $label in AT&T syntax: undefined reference to [label-name]
I learn assembler(AT&T). I tried to write program to find the length of the biggest string in record.
During linking with command
ld person-data-with-names-pointer.o find-longest-name.o -o longest
I got error
ld: person-data-with-names-pointer.o: in function `people': (.data+0x55): undefined reference to `$john_silver' ld: (.data+0x85): undefined reference to `$billy_bones' ld: (.data+0xb5): undefined reference to `$black_beard' ld: (.data+0xe5): undefined reference to `$dave_jones' ld: (.data+0x115): undefined reference to `$jack_the_sparrow' ld: (.data+0x145): undefined reference to `$genry_morgan'
full listing of
.section .data .global people, numpeople numpeople: # Calculate the number of people in array .quad (endpeople - people)/PERSON_RECORD_SIZE people: .quad $john_silver, 200, 10, 2, 74, 20 .quad $billy_bones, 280, 14, 2, 74, 44 .quad $black_beard, 150, 8, 1, 68, 30 .quad $dave_jones, 250, 14, 3, 75, 24 .quad $jack_the_sparrow, 250, 10, 2, 70, 11 .quad $genry_morgan, 180, 11, 5, 69, 65 endpeople: # Marks the end of the array for calculation purposes john_silver: .ascii "John Silver" billy_bones: .ascii "Billy Bones" black_beard: .ascii "Black Beard" dave_jones: .ascii "Dave Jones" jack_the_sparrow: .ascii "Jack The Sparrow" genry_morgan: .ascii "Genry Morgan" # Describes the components of the struct .global NAME_PTR_OFFSET, WEIGHT_OFFSET, SHOE_OFFSET .global HAIR_OFFSET, HEIGHT_OFFSET, AGE_OFFSET .equ NAME_PTR_OFFSET, 0 .equ WEIGHT_OFFSET, 8 .equ SHOE_OFFSET, 16 .equ HAIR_OFFSET, 24 .equ HEIGHT_OFFSET, 32 .equ AGE_OFFSET, 40 # Total size of the struct .global PERSON_RECORD_SIZE .equ PERSON_RECORD_SIZE, 48
I was tried to move labels but nothing works. 🙁
Solution – 1
.quad isn’t a real instruction like
mov; a symbol name will always be taken as the symbol address, and a
$ will be taken as a literal part of the symbol name. As the linker error shows you, it’s looking for symbol names like
.quad john_silver, 200, 10, 2, 74, 20 .quad billy_bones, 280, 14, 2, 74, 44
For the same reason you write
.quad 123 not
Like most assemblers, there’s no syntax that will get GAS to copy data from one
.string to another; if you wanted the same data in two places, you’d define a macro or
.equ assemble-time constant and emit the same data separately. You can’t read back in some bytes emitted into an output section by a different source line.
So there’s nothing equivalent to the immediate vs. memory-operand possibility here, which is what
$ distinguishes in instructions.
mov symbol, %rax is a load of 8 bytes from that address (using 32-bit absolute addressing, not RIP-relative), vs.
mov $symbol, %rax is the address as a 32-bit sign-extended immediate.
In 64-bit code, normally you’d use
mov symbol(%rip), %rax or
lea symbol(%rip), %rax, or in non-PIE executables, 32-bit absolute
mov $symbol, %eax. See How to load address of function or label into register