assembly AT&T语法中的.quad $标签:未定义对[标签名称]的引用

w8biq8rn  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(129)

我学习汇编语言(AT&T)。我试着写程序来找出记录中最大的字符串的长度。在用命令链接的过程中

ld person-data-with-names-pointer.o find-longest-name.o -o longest

出现错误

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'

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

英译汉我试着移动标签,但没有任何效果

vtwuwzda

vtwuwzda1#

.quad不是像mov那样的真实的指令;一个符号名将总是被当作符号地址,而一个$将被当作符号名的文字部分。正如链接器错误所显示的,它正在查找类似$john_silver的符号名,而不是john_silver

.quad john_silver, 200, 10, 2, 74, 20 
    .quad billy_bones, 280, 14, 2, 74, 44

出于同样的原因,你写.quad 123而不是.quad $123
与大多数汇编程序一样,没有语法可以让GAS将数据从一个.quad.string复制到另一个;如果您希望在两个位置使用相同的数据,则需要定义一个宏或.equ汇编时常量,并分别发出相同的数据。
因此,这里没有任何等价于立即数与内存操作数的可能性,这是$在指令中的区别。
mov symbol, %rax是从该地址加载8个字节(使用32位绝对寻址,而不是RIP相对寻址),而mov $symbol, %rax是32位符号扩展立即数形式的地址。
在64位代码中,通常使用mov symbol(%rip), %raxlea symbol(%rip), %rax,或者在非PIE可执行文件中,使用32位绝对值mov $symbol, %eax。请参见 * How to load address of function or label into register *

相关问题