Calling the C-function _printf from NASM causes a Segmentation Fault

后端 未结 1 1557
小鲜肉
小鲜肉 2021-01-27 08:36

I\'ve been trying to learn 64-bit assembly on both Mac-OS and Windows using NASM.

My code is

extern _printf

section .data
    msg db \"Hello World!\", 1         


        
相关标签:
1条回答
  • 2021-01-27 08:47

    ~~You need to setup a stack frame before calling _printf

    TL;DR: The System V AMD64 ABI requires the stack-pointer to be 16-byte-aligned. By the time of calling _printf, the stack-pointer is misaligned by 8 bytes.

    Debugging the binary with LLDB gives:

    frame #0: 0x00007fff527d430a libdyld.dylib`stack_not_16_byte_aligned_error

    MacOS uses the System V AMD64 ABI and therefore relies on 16-byte alignment for the stack-pointer (see this question), in short this means the stack-pointer (rsp) should always be divisible by 16 when calling a function.

    By the time of calling _printf, the stack-pointer (rsp) is misaligned by 8 bytes. How did this come?

    I found the answer on this page, calling the _main function pushes the return address (8 bytes) on the stack and therefore misaligns it.

    My initial idea - the setup of the stack frame - pushed another address on the stack and therefore rsp was divisible by 16 again.

    However an easier solution would be just sub rsp, 8 as suggested by Margaret Bloom

    Change your code to:

    extern _printf
    
    section .data
        msg: db "Hello World!", 10, 0
    
    section .text
        global _main
    
    _main:
        ;; Fix the stack alignment
        sub rsp, 8
        mov rax, 0
        mov rdi, msg
        call _printf
    
        mov rax, 0x2000001
        mov rdi, 0
        syscall
    

    Tested on macOS 10.13.6

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