首先,您在 Mac OS X 上使用旧的 32 位 Linux 内核调用约定——这绝对行不通。
其次,Mac OS X 中的系统调用以不同的方式构造——它们都有一个前导类标识符和一个系统调用号。该类可以是 Mach、BSD 或其他(参见XNU 源代码中的此处),并且向左移动 24 位。正常的 BSD 系统调用具有类2
,因此从0x2000000
. 类0
中的系统调用无效。
根据SysV AMD64 ABI的§A.2.1 以及Mac OS X,系统调用 id(连同其在 XNU 上的类!)转到%rax
(或%eax
在 XNU 上未使用高 32 位时)。第一个论点进入%rdi
。接下来去%rsi
。等等。%rcx
被内核使用并且它的值被破坏,这就是为什么在进行系统调用之前所有函数都libc.dyld
将它保存到%r10
中(类似于来自的kernel_trap
宏syscall_sw.h
)。
第三,调用 Mach-O 二进制文件中的代码部分,__text
而不是.text
像在 Linux ELF 中那样,并且也驻留在__TEXT
段中,统称为(__TEXT,__text)
(如果选择 Mach-O 作为目标对象类型,则nasm
自动翻译) - 请参阅Mac OS X ABI Mach-O 文件格式参考. 即使您得到正确的组装说明,将它们放在错误的段/节中也会导致总线错误。您可以使用该指令(请参阅此处以了解指令语法),也可以使用(更简单的)指令,或者您可以完全放弃它,因为假设没有提供任何选项(请参阅手册页)。.text
.section __TEXT,__text
.text
-n
as
as
ld
第四,调用Mach-O 的默认入口点start
(尽管您已经知道,它可以通过-e
链接器选项进行更改)。
鉴于以上所有内容,您应该将汇编源代码修改为如下所示:
; You could also add one of the following directives for completeness
; .text
; or
; .section __TEXT,__text
.globl start
start:
movl $0x2000001, %eax
movl $32, %edi
syscall
在这里,按预期工作:
$ as -o exit.o exit.s; ld -o exit exit.o
$ ./exit; echo $?
32