这是代码(exit.s):
.section .data,
.section .text,
.globl _start
_start:
movl $1, %eax
movl $32, %ebx
syscall
当我执行
" as exit.s -o exit.o && ld exit.o -o exit -e _start && ./exit"
返回值为“总线错误:10”,“
echo $?
”的输出为138我还尝试了以下有关此问题的正确答案的示例:Process command line in Linux 64 bit
stil得到“总线错误” ...
最佳答案
首先,您在Mac OS X上使用了旧的32位Linux内核调用约定-这绝对不起作用。
其次,Mac OS X中的syscall具有不同的结构-它们都具有前导类标识符和syscall号。该类可以是Mach,BSD或其他类(请参见XNU源文件中的here),并向左移动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
,而不是Linux ELF中的.text
,并且也驻留在__TEXT
段中,统称为(__TEXT,__text)
(nasm
会根据需要自动翻译.text
如果选择了Mach-O作为目标对象类型)-请参见Mac OS X ABI Mach-O File Format Reference。即使正确安装了说明,将它们放在错误的段/节中也会导致总线错误。您可以使用.section __TEXT,__text
指令(有关指令语法,请参见here),也可以使用(更简单的).text
指令,或者可以将其完全删除,因为假定没有提供-n
选项。到as
(请参见as
的联机帮助页)。
第四,Mach-O ld
的默认入口点称为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
关于macos - 基本程序集不能在Mac(x86_64 + Lion)上运行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11179400/