标签后面是否有冒号或等号?

问题描述 投票:0回答:1

具有此:

.text
    .globl main
str:
    .string "hello world"
len = .-str #a strange assignment
main:
    mov $1, %eax
    mov $1, %edi
    movabs $str, %rsi
    mov $len, %rdx
    syscall 
    call exit

1]这里是带有冒号的str(正如我通常看到的),但是len=分配。我不认为这是因为str是地址,而len是数字(因此是不同的类型),但是为什么可以分配不同的方式呢?还是两个标签?

2)当我可以使用mov str(%rip), %rsi时为何使用movabs $str, %rsi

assembly x86-64 gas
1个回答
0
投票

标签后跟:

=不是标签,它以.set.equ的方式将符号定义为汇编时间常数。这使汇编程序可以在汇编时为您计算字符串的长度。

.是当前位置。将.视为此行开头的隐式标签。您可以等效地在字符串后放置str_end:标签并完成len = str_end - str


为什么可以使用mov str(%rip), %rsi,何时可以使用movabs $str, %rsi

这些不相等! mov str(%rip), %rsi将从该地址加载8个字节,并将字符串数据保存到寄存器中。但是您需要对寄存器中的字符串使用pointer作为write(int fd, void *buf, size_t len)系统调用的arg。在调试器和/或strace中进行尝试,然后观察失败。

这就是为什么此代码中的movabs使用$str将地址作为64位立即数获取的原因。

但是,这是the worst way to put a label/symbol address into a registermovabs的立即数为8个字节,总共等于10个字节的指令,并且绝对是当加载程序选择可执行文件的实际基址时,它需要在PIE可执行文件或库(ELF共享对象)中进行运行时修复。

您实际上想要LEA str(%rip), %rsi(7个字节),或在non-PIE Linux executable where static addresses fit in the low 31 bits of address space, mov $str, %esi中。

© www.soinside.com 2019 - 2024. All rights reserved.