gpt4 book ai didi

macos - MacOS 程序集的 64 位系统调用文档

转载 作者:行者123 更新时间:2023-12-04 14:25:00 24 4
gpt4 key购买 nike

我很难找到在 MacOS 上编写 64 位程序集的好文档。

64-bit SysV ABI在第 A.2.1 节和 this SO post 中说以下内容引用它:

  • A system-call is done via the syscall instruction. The kernel destroys registers %rcx and %r11.

  • Returning from the syscall, register %rax contains the result of the system-call. A value in the range between -4095 and -1 indicates an error, it is -errno.



这两句话在 Linux 上没问题,但在 macOS Sierra 上是错误的,代码如下:
global _start
extern _exit

section .text
_start:

; Align stack to 16 bytes for libc
and rsp, 0xFFFFFFFFFFFFFFF0

; Call write
mov rdx, 12 ; size
mov rsi, hello ; buf
mov edi, 1 ; fd
mov rax, 0x2000004 ; write ; replace to mov rax, 0x1 on linux
syscall

jc .err ; Jumps on error on macOS, but why?
jnc .ok

.err:
mov rdi, -1
call _exit ; exit(-1)

.ok:
; Expect rdx to be 12, but it isn't on macOS!
mov rdi, rdx
call _exit ; exit(rdx)

; String for write
section .data
hello:
.str db `Hello world\n`
.len equ $-hello.str

用 NASM 编译:
; MacOS: nasm -f macho64 syscall.asm && ld syscall.o -lc -macosx_version_min 10.12 -e _start -o syscall
; Linux: nasm -f elf64 syscall.asm -o syscall.o && ld syscall.o -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o syscall

在 macOS 上运行:
./syscall      # Return value 0
./syscall >&- # Return value 255 (-1)

我发现:
  • 系统调用返回 errno an 设置出错时的进位标志,而不是返回 -errnorax
  • rdx注册表被 syscall 破坏了
  • 在 Linux 上,一切正常

  • 为什么是 rdx重创?为什么系统调用不返回 -errno ?我在哪里可以找到真正的文档?

    我发现有人谈论系统调用错误的进位标志的唯一地方是 here

    最佳答案

    我用过这个:

    # as hello.asm -o hello.o
    # ld hello.o -macosx_version_min 10.13 -e _main -o hello -lSystem
    .section __DATA,__data
    str:
    .asciz "Hello world!\n"

    .section __TEXT,__text
    .globl _main
    _main:
    movl $0x2000004, %eax # preparing system call 4
    movl $1, %edi # STDOUT file descriptor is 1
    movq str@GOTPCREL(%rip), %rsi # The value to print
    movq $13, %rdx # the size of the value to print
    syscall

    movl %eax, %edi
    movl $0x2000001, %eax # exit (return value of the call to write())
    syscall

    并且能够将返回值捕获到 eax .这里的返回值是 write实际写入的字节数系统调用。是的,MacOS 是 BSD 变体,它是进位标志,告诉您系统调用是否错误(errno 只是一个外部链接变量)。
    # hello_asm.s
    # as hello_asm.s -o hello_asm.o
    # ld hello_asm.o -e _main -o hello_asm
    .section __DATA,__data
    str:
    .asciz "Hello world!\n"
    good:
    .asciz "OK\n"

    .section __TEXT,__text
    .globl _main
    _main:
    movl $0x2000004, %eax # preparing system call 4
    movl $5, %edi # STDOUT file descriptor is 5
    movq str@GOTPCREL(%rip), %rsi # The value to print
    movq $13, %rdx # the size of the value to print
    syscall

    jc err

    movl $0x2000004, %eax # preparing system call 4
    movl $1, %edi # STDOUT file descriptor is 1
    movq good@GOTPCREL(%rip), %rsi # The value to print
    movq $3, %rdx # the size of the value to print
    syscall
    movl $0, %edi
    movl $0x2000001, %eax # exit 0
    syscall
    err:
    movl $1, %edi
    movl $0x2000001, %eax # exit 1
    syscall

    这将退出并显示错误代码 1,因为使用了描述符 5,如果您尝试使用描述符 1,那么它将打印另一条消息并以 0 退出。

    关于macos - MacOS 程序集的 64 位系统调用文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47834513/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com