如何在气体中设置长整数

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

为什么不能在气体中使用标签代替.set

.data
    .globl _start
str: .asciz "Hello world"
len: .long 13 #if used len = 13, no problem
    .text
_start:
    mov $1, %eax
    mov $1, %edi
    movabs $str, %rsi
    mov $len, %rdx
    syscall
    mov $60, %rax
    xor %edi, %edi
    syscall

这给了我一个错误。我怀疑符号len会显示地址.data+0xd吗?并移至R_X86_64_32?因此,我声明的变量不是从值13声明的变量,而是从上述地址获取值的变量?那么最后,len不是常规变量而是指针吗?

输出:

@@ @�� @ld
 @ @  @a.ostrlen__bss_start_edata_end.symtab.strtab.shstrtab.note.gnu.property.text.data .@(4 @ !%=!:
assembly x86-64 gas att
1个回答
0
投票

这里的问题夫妇:

  1. $中的mov $len, %rdx在RDX中放置len的地址。如果删除它,它将使用您想要的len(13)中的内容。
  2. 我认为您想使用.quad而不是.long,它们分别是64位和32位。如果您确实希望len成为long,则应使用movzx len, %rdx。这会将len处的32位值零扩展到RDX。如果没有这个,如果您说.byte 0xc,那么您将获得更大的数量。
    • 或者,您可以使用mov len, %edx,它与movzx基本上具有相同的功能,因为将32位移入64位寄存器会清除前32位。但是,我认为这有点使含义模糊不清。
  3. str处的数据长度为12个字符,包括空字节,而不是13个字符。如果改为使用len: .quad . - str,则可以避免每次都要重新计算。 .表示当前地址。

关于len = 13(又称.set len, 13)为什么起作用的原因,mov $len, %rdx变成了mov $13, %rdx,它只是将64位13转换为RDX。如果$不存在,它将移入您不想要的存储器地址13中的内容。如果这样选择,还可以使用#define len $13,这将在以后消除对$的需要,但是在这种情况下,我不建议这样做。

最后,我会这样做:

.data
    .globl _start

str: 
    .asciz "Hello world"
len:
    .quad . - str

.text
_start:
    // Write to STDOUT
    mov $1, %eax
    mov $1, %edi
    movabs $str, %rsi
    mov len, %rdx
    syscall

    // Exit
    mov $60, %rax
    xor %edi, %edi
    syscall
© www.soinside.com 2019 - 2024. All rights reserved.