首先,您在 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-nasas
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