如何在 MacOS 上正确使用“write”系统调用打印到标准输出?

Gre*_*ers 5 macos assembly x86-64 gnu-assembler system-calls

我看过类似的问题,但似乎找不到我的代码有什么问题。

我正在尝试在 MacOS 上进行“write”系统调用以将字符串打印到标准输出。

我能够printf完美地做到这一点,并且熟悉在 x64 汇编中调用其他函数。

然而,这是我第一次尝试syscall

我正在使用 GCC 的 GAS 汇编器。

这是我的代码:

.section __TEXT,__text

.globl _main

_main:
    pushq %rbp
    movq %rsp, %rbp

    subq $32, %rsp

    movq $0x20000004, %rax
    movq $1, %rdi
    leaq syscall_str(%rip), %rsi
    movq $25, %rdx
    syscall

    jc error

    xorq %rax, %rax

    leave
    ret

error:
    movq $1, %rax
    leave
    ret

.section __DATA,__data
syscall_str:
    .asciz "Printed with a syscall.\n"
Run Code Online (Sandbox Code Playgroud)

看起来没有任何错误;根本没有写入任何内容stdout

我知道它start通常用作 MacOS 上可执行文件的起点,但它不能使用 GCC 进行编译。

小智 6

您使用的 MacOS 系统调用号不正确。用户系统调用的基址是0x2000000。您错误地使用了该基础。结果,您已经按照应有的方式对writeSYSCALL进行了编码(少一零)$0x20000004$0x2000004

根据经验,请确保您在寄存器中使用正确的 SYSCALL 编号值%rax;确保您为 SYSCALL 使用正确的参数write。SYSCALLwrite需要以下参数:

  • %rdi:要写入的文件描述符(例如 1 表示标准输出)
  • %rsi:指向包含要写入的数据的缓冲区的指针
  • %rdx:要写入的字节数
  • 在 macOS 上,您需要使用syscall指令来调用系统调用。