【问题标题】:Mac OS X assembly and sys call causing Bus Error 10Mac OS X 程序集和系统调用导致总线错误 10
【发布时间】:2014-01-15 05:41:07
【问题描述】:

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

这是一个基本的“你好,世界!”程序只使用系统调用。

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”和换行符,但随后返回 Bus Error: 10(错误的内存地址)。

但如果我这样做:

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

我没有收到总线错误。

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

【问题讨论】:

  • 不确定:也许系统调用不保留 rax?

标签: macos assembly


【解决方案1】:

rax 寄存器不会被第一个 syscall 保留,因此简单地将 al 设置为 1 不会为 rax 中的 next 系统调用提供正确的值因为它使所有高位保持不变。 不会给你总线错误的方法是重新填充rax所有位。

由于write 旨在返回实际写入的字节数,该字节数在rax 中返回,确保您需要完全为下一个syscall 填充它。可以在the Wikipedia calling convention page 上找到对这种使用rax 的返回代码的支持,其中声明了System V AMD64 ABI

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 文档中也有详细说明。

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

mov rax, 0x2000001
mov rdi, 0
syscall

退出。事实上,我会为 both 系统调用使用该方法来简化源代码:

SECTION .text
global start

start:
mov rax, 0x2000004      ; syscall 4: write (
mov rdi, 1              ;    fd,
mov rsi, Msg            ;    buffer,
mov rdx, Len            ;    size
syscall                 ; )

mov rax, 0x2000001      ; syscall 1: exit (
mov rdi, 0              ;    retcode
syscall                 ; )

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

【讨论】:

  • 有道理。感谢您指出对我来说显而易见的事情。是否有任何网站或在线资料可以深入介绍您推荐的 Unix 系统调用?
  • @pmbotter,将“System V AMD64 ABI”插入谷歌通常是我开始的地方:-)x86-64.org/documentation/abi.pdf有一个PDF作为第一个链接,你应该看看。
  • mov al , 0x2000001 mov rdi, 0 应该是 mov rax , 0x2000001 有一点错别字
  • @violentr,非常感谢,我已将al 更改为rax,但我没有删除rdi 的加载(如果这确实是您在评论中建议的) )。虽然 from 函数的返回值在 rax 中,但这是一个 to 函数的调用,并且 ABI 似乎需要 rdi 中的第一个参数(退出代码) .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
  • 2018-04-25
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
相关资源
最近更新 更多