问题
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!", 10, 0
section .text
global _main
_main:
mov rax, 0
mov rdi, msg
call _printf
mov rax, 0x2000001
mov rdi, 0
syscall
and I compile it with
nasm -f macho64 -o main.o main.asm
gcc -o main main.o
While trying to call _printf
, I got the error
Segmentation fault: 11
When I remove the call to _printf
, my code runs fine.
Why does the call to _printf
cause a segmentation fault?
I have found the ABI Calling Convention here, but had no luck successfully calling a C-function.
I would expect Hello World!
to be printedd, however I get 'Segmentation Fault: 11' instead.
回答1:
~~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
来源:https://stackoverflow.com/questions/56991218/calling-the-c-function-printf-from-nasm-causes-a-segmentation-fault