# .quad \$label in AT&T syntax: undefined reference to [label-name]

## .quad \$label in AT&T syntax: undefined reference to [label-name]

Contents

Problem Description:

I learn assembler(AT&T). I tried to write program to find the length of the biggest string in record.

``````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 `person-data-with-names-pointer.s`

``````.section .data

.global people, numpeople
numpeople:
# Calculate the number of people in array
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 `\$john_silver`, not `john_silver`.

``````    .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 `.quad \$123`.

Like most assemblers, there’s no syntax that will get GAS to copy data from one `.quad` or `.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

Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.