使用GNU assember进行系统调用时的Segfault

时间:2017-11-07 23:51:04

标签: linux assembly x86 system-calls gnu

我试图理解为什么as在汇编级别进行系统调用时的行为与nasm不同。因为我是一个贪婪的惩罚,我使用英特尔语法。这是我的计划:

    .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

我使用as -o prog.o prog.s汇编并与ld -s -o prog prog.o建立链接。

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

因为它永远不会正常退出。 _start没有父堆栈框架,因此从中返回会导致崩溃。

您可以从main返回标准库的_start实施电话exit,但如果您正在编写自己的_start你需要自己调用exit,因为没有父堆栈帧可以返回。