使用 GNU 汇编程序进行系统调用时出现段错误

Segfault when doing syscall using GNU assember

我试图理解为什么 as 在汇编级别执行系统调用时的行为与 nasm 不同。因为我是惩罚的贪吃者,所以我使用的是 Intel 语法。这是我的程序:

    .intel_syntax noprefix
    .section    .rodata
.LC0:
    .string "Hello world!\n"
    .text
    .globl  _start
    .type   _start, @function
_start:
    mov edx, 13
    mov ecx, OFFSET FLAT:.LC0
    mov eax, 4
    int 0x80
    ret

我 assemble 与 as -o prog.o prog.s 和 link 与 ld -s -o prog prog.o.

但是当我 运行 它时,我得到:

$ ./prog 
Hello world!
Segmentation fault (core dumped)

GDB 在这里不是特别有用。当我在 retstepi 时,它显示 Cannot access memory at address 0x1。这令人费解,因为 ESP 的值是:

(gdb) info registers esp
info registers esp
esp            0xbffff660       0xbffff660

为什么这个程序会出现段错误?

因为它永远不会正常退出。 _start 没有父堆栈帧,因此 return 从中读取会导致崩溃。

您可以从 main return 获得标准库的 _start 实现调用 exit,但如果您正在编写自己的 _start,您需要自己调用 exit,因为没有要 return 的父堆栈帧。