Mac OS X程序集和sys调用导致总线错误10

时间:2014-01-15 05:41:07

标签: macos assembly

尝试在我的Macbook Pro(Intel i7,64位)上运行程序集并遇到了一个奇怪的错误。

这是一个基本的“Hello,world!”程序只使用系统调用。

SECTION .text
global start

start:
mov rax, 2
shl rax, 24
add al , 4
mov rdi, 1
mov rsi, Msg
mov rdx, Len
syscall

mov al , 1
mov rdi, 0
syscall

SECTION .data
Msg db `Hello, world!\n`
Len: equ $-Msg

与NASM 2.11组装 控制台命令:

nasm -f macho64 -o main.o main.s
ld main.o

它打印“Hello,world”和换行符,但随后返回总线错误:10(错误的内存地址)。

但如果我这样做:

mov rax, 2
shl rax, 24
add al , 1

我没有收到总线错误。

问题是:为什么我不能使用“mov al,1”更改不同调用的rax的第一个字节

1 个答案:

答案 0 :(得分:2)

第一个rax并未保留syscall注册,因此只需将al设置为1,就无法为 next < / em>系统调用rax,因为它保持所有高位不变。 给出总线错误的方法是重新填充 rax的所有位的方法。

由于write是为了返回实际写入的字节数,所以返回rax,确保您需要将完全填入下一个{ {1}}。可以在the Wikipedia calling convention page上找到支持使用syscall获取返回代码的内容,其中列出rax

  

System V AMD64 ABI [11]的调用约定遵循Solaris,GNU / Linux,FreeBSD, Mac OS X,以及其他类UNIX或POSIX兼容的操作系统。前六个整数或指针参数在寄存器RDI,RSI,RDX,RCX,R8和R9中传递,而XMM0,XMM1,XMM2,XMM3,XMM4,XMM5,XMM6和XMM7用于浮点参数。对于系统调用,使用R10代替RCX。[11]与Microsoft x64调用约定一样,其他参数在堆栈上传递,返回值存储在RAX中。

附录A中的System V Application Binary Interface, AMD64 Architecture Processor Supplement文件中也对此进行了详细说明。

在修复代码方面,最好不要执行完整的填充序列(不必要的位移):

System V AMD64 ABI

退出。实际上,我将两个系统调用的方法用于简化源代码:

mov rax, 0x2000001
mov rdi, 0
syscall