我如何在 x64 上 sys_write 多个 ASCII 字符?

How do I sys_write multiple ASCII characters on x64?

我正在学习汇编,许多指南解释了如何 sys_write 但仅使用存储在 .text 中的数据。我想打印存储在堆栈中的多个 ASCII 字符。

global _start

section .data

section .text

_start:
    push rbp
    mov rbp, rsp

    sub rsp, 16
    mov QWORD [rbp], 47
    mov QWORD [rbp - 8], 46
    
    mov rax, 1
    mov rdi, 1
    lea rsi, [rbp]
    mov rdx, 2
    syscall

    pop rbp
    
    mov rax, 60
    mov rdi, 0
    syscall

上面的代码设置了堆栈帧(对于示例没有用),为局部变量腾出空间并将 47 和 46 的 ASCII 字符放入堆栈。然后它将第一个 ASCII 字符的地址加载到 rsi 并调用 sys_write。最后,它调用 sys_exit.

但是,当我 运行 代码时,它只打印:/^@。 运行 strace 产生以下输出:

execve("./a.out", ["./a.out"], 0x7ffd1d1c2280 /* 60 vars */) = 0
write(1, "/[=12=]", 2/[=12=])                      = 2
exit(0)                                 = ?
+++ exited with 0 +++

我觉得我对 lea[rbp] 存在根本性的误解,但我对汇编的了解还不够多,无法知道我遗漏了什么。

我假设这是在 linux 或 linux 之类的东西上,但是您的 read 需要一组字节打包的字符,因此以下更改(保持你的 16 字节对齐堆栈)

    sub rsp, 16
    mov BYTE [rbp], 47
    mov BYTE [rbp-1], 46
    
    mov rax, 1
    mov rdi, 1
    lea rsi, [rbp-1]
    mov rdx, 2
    syscall

打印

./