【问题标题】:Are labels followed by colon or equal sign in gas?标签后面是冒号还是等号气体?
【发布时间】:2020-06-07 10:07:58
【问题描述】:

有这个:

.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 gnu-assembler


    【解决方案1】:

    标签后跟:

    = 不是标签,它以 .set.equ 的方式将符号定义为汇编时常量。这是让汇编器在汇编时为您计算字符串的长度。

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


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

    这些不相等! mov str(%rip), %rsi 将从该地址加载 8 个字节,将字符串数据放入寄存器。但是您需要一个指向寄存器中字符串的 指针 作为 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

    【讨论】:

    猜你喜欢
    • 2012-09-25
    • 2012-10-09
    • 2012-03-01
    • 2012-03-10
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    相关资源
    最近更新 更多