为什么这个汇编代码会抛出段错误?

Why does this assembly code throw a seg fault?

本书 Assembly Language Step by Step 提供了以下代码作为沙箱:

section .data
section .text

global _start                

_start:

    nop
    //insert sandbox code here
    nop

我在沙箱 space 中包含的任何示例都会造成分段错误。例如,添加此代码:

mov ax, 067FEh
mov bx, ax
mov cl, bh
mov ch, bl

然后编译:

nasm -f macho sandbox.asm
ld -o sandbox -e _start sandbox.o

当我 运行 在我的 OS/X 上创建段错误时。有没有办法获取有关导致分段错误的原因的更多信息?

您遇到的问题是您创建的程序在您编写的代码末尾运行。

当您的程序执行时,加载程序最终会向您的 _start 发出 jmp。然后你的代码运行,但你没有任何东西可以 return 到最后的 OS,所以它会继续 运行,执行你的代码之后恰好在 RAM 中的任何字节.

最简单的解决方法是正确退出代码。例如:

mov eax, 0x1              ; system call number for exit
sub esp, 4                ; OS X system calls needs "extra space" on stack
int 0x80       

由于您没有生成任何实际输出,因此您需要使用调试器逐步查看发生了什么。编译后可以使用lldb单步执行。

lldb ./sandbox
image dump sections

记下列出的可执行文件(不是 dyld)类型 code 的地址。它可能是 0x0000000000001fe6。在 lldb 中继续:

b s -a 0x0000000000001fe6
run
register read
step
register read
step
register read

此时您应该已经过了 NOP 并看到寄存器中发生了变化。玩得开心!