assembly 如何正确使用MacOS上的“write”系统调用来打印到stdout?

t3irkdon  于 2022-12-27  发布在  Mac
关注(0)|答案(1)|浏览(142)

我看过类似的问题,但似乎找不到我的代码有什么问题。
我试图在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"

似乎没有任何错误;简单地没有任何东西被写入stdout
我知道start通常用作MacOS上可执行文件的起点,但它不能用GCC编译。

9cbw7uwe

9cbw7uwe1#

您在MacOS中使用了错误的SYSCALL编号。用户系统调用的基数是0x 2000000。您错误地使用了该基数。因此,您将write SYSCALL编码为$0x20000004,而它应该是$0x2000004(减一个零)
根据经验,请确保%rax寄存器中SYSCALL编号的值正确;确保为write SYSCALL使用了正确的参数。write SYSCALL需要以下参数:

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

相关问题