基本程序集在Mac上不起作用(x86_64 + Lion)?

spr*_*der 5 macos assembly x86-64 system-calls

这是代码(exit.s):

.section .data,
.section .text,
.globl _start
_start:
    movl $1, %eax
    movl $32, %ebx
    syscall
Run Code Online (Sandbox Code Playgroud)

当我执行 " as exit.s -o exit.o && ld exit.o -o exit -e _start && ./exit"

返回是"总线错误:10",输出" echo $?"是138

我也在这个问题中尝试了正确答案的例子:Linux 64位中的进程命令行

stil得到"总线错误"......

Hri*_*iev 14

首先,您在Mac OS X上使用旧的32位Linux内核调用约定 - 这绝对不起作用.

其次,Mac OS X中的系统调用以不同的方式构成 - 它们都具有前导类标识符系统调用号.这个类可以是马赫,BSD或其他的东西(见这里的XNU源)和移动24位到左侧.普通的BSD系统调用具有类2,因此从中开始0x2000000.在类系统调用0无效的.

根据SysV AMD64 ABI的 §A.2.1,以及Mac OS X,syscall 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自动转换.text) - 请参阅Mac OS X ABI Mach-O文件格式参考.即使您获得正确的装配说明,将它们放在错误的段/部分也会导致总线错误.您既可以使用该.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
Run Code Online (Sandbox Code Playgroud)

在这里,按预期工作:

$ as -o exit.o exit.s; ld -o exit exit.o
$ ./exit; echo $?
32
Run Code Online (Sandbox Code Playgroud)