Nasm segmentation fault on RET in _start

前端 未结 1 1034
粉色の甜心
粉色の甜心 2020-11-27 08:04
section .text
     global _start
_start:
     nop
main:
     mov eax, 1
     mov ebx, 2
     xor eax, eax
     ret

I compile with these commands:

相关标签:
1条回答
  • 2020-11-27 08:41

    Because ret is NOT the proper way to exit a program in Linux, Windows, or Mac!!!!

    _start is not a function, there is no return address on the stack because there is no user-space caller to return to. Execution in user-space started here (in a static executable), at the process entry point. (Or with dynamic linking, it jumped here after the dynamic linker finished, but same result).

    On Linux / OS X, the stack pointer is pointing at argc on entry to _start (see the i386 or x86-64 System V ABI doc for more details on the process startup environment); the kernel puts command line args into user-space stack memory before starting user-space. (So if you do try to ret, EIP/RIP = argc = a small integer, not a valid address. If your debugger shows a fault at address 0x00000001 or something, that's why.)


    For Windows it is ExitProcess and Linux is is system call - int 80H using sys_exit, for x86 or using syscall using 60 for 64Bit or a call to exit from the C Library if you are linking to it.

    32 bit Linux

    mov     eax, sys_exit ; sys_exit = 1
    xor     ebx, ebx
    int     80H
    

    64 bit Linux

    mov     rax, 60
    xor     rdi, rdi
    syscall
    

    Windows

    push    0
    call    ExitProcess
    

    Or Windows/Linux linking against the C Library

    call    exit
    

    exit (unlike a raw exit system call or libc _exit) will flush stdio buffers first. If you used printf from _start, use exit to make sure all output is printed before you exit, even if stdout is redirected to a file (making stdout full-buffered, not line-buffered).

    It's generally recommended that if you use libc functions, you write a main function and link with gcc so it's called by the normal CRT start functions which you can ret to.

    Defining main as something that _start falls through into doesn't make it special, it's just confusing to use a main label if it's not like a C main function called by a _start that's prepared to exit after main returns.

    0 讨论(0)
提交回复
热议问题