简体   繁体   English

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

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

I learn assembler(AT&T).我学习汇编程序(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 person-data-with-names-pointer.s person-data-with-names-pointer.s完整列表

.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\0"
billy_bones: 
    .ascii "Billy Bones\0"
black_beard: 
    .ascii "Black Beard\0"
dave_jones: 
    .ascii "Dave Jones\0"
jack_the_sparrow: 
    .ascii "Jack The Sparrow\0"
genry_morgan:
    .ascii "Genry Morgan\0" 
# 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.我试图移动标签,但没有任何效果。 :( :(

.quad isn't a real instruction like mov ; .quad不是像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 .如 linker 错误所示,它正在寻找像$john_silver这样的符号名称,而不是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 .出于同样的原因,您写.quad 123而不是.quad $123

Like most assemblers, there's no syntax that will get GAS to copy data from one .quad or .string to another;像大多数汇编器一样,没有语法可以让 GAS 将数据从一个.quad.string到另一个; 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.如果你想在两个地方使用相同的数据,你可以定义一个宏或.equ汇编时常量并分别发出相同的数据。 You can't read back in some bytes emitted into an output section by a different source line.您无法读回由不同的源代码行发送到 output 部分的某些字节。

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. mov symbol, %rax是从该地址加载 8 个字节(使用 32 位绝对寻址,而不是 RIP 相对),而mov $symbol, %rax是作为 32 位符号扩展立即数的地址。
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 .在 64 位代码中,通常您会使用mov symbol(%rip), %raxlea symbol(%rip), %rax ,或者在非 PIE 可执行文件中,32 位绝对mov $symbol, %eax See How to load address of function or label into register请参阅如何将 function 或 label 的地址加载到寄存器中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM