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)