Bil*_*low 5 macos assembly x86-64 system-calls abi
我无法找到在 MacOS 上编写 64 位程序集的良好文档。
64位 SysV ABI在 A.2.1 节中说了以下内容,并且此 SO 帖子引用了它:
系统调用是通过 syscall 指令完成的。内核销毁寄存器%rcx 和%r11。
从系统调用返回,寄存器 %rax 包含系统调用的结果。-4095 到 -1 之间的值表示错误,它是 -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
Run Code Online (Sandbox Code Playgroud)
使用 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
Run Code Online (Sandbox Code Playgroud)
在 macOS 上运行:
./syscall # Return value 0
./syscall >&- # Return value 255 (-1)
Run Code Online (Sandbox Code Playgroud)
我发现:
errno错误时设置进位标志,而不是-errno返回raxrdx寄存器被破坏syscall为何rdx被砸?为什么系统调用不返回-errno?我在哪里可以找到真正的文档?
我发现有人谈论系统调用错误的进位标志的唯一地方是这里
我用过这个:
# 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
Run Code Online (Sandbox Code Playgroud)
并能够将返回值捕获到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
Run Code Online (Sandbox Code Playgroud)
这将以错误代码 1 退出,因为使用了描述符 5,如果您尝试描述符 1,那么它将打印另一条消息并以 0 退出。
| 归档时间: |
|
| 查看次数: |
9218 次 |
| 最近记录: |