0

For some reason when I run this code it works perfectly but also causes a segfault after it is done.

global main
extern printf

section .text

main:  
    push rbp
    mov rbp, rsp

    mov rcx, format
    call printf

    mov rax, 0
    pop rbp
    ret

section .data
format: db "Hello!", 10, 0

I am compiling it using NASM and mingw_w64 GCC

nasm -f win64 main.asm
gcc main.obj -o main.exe

Here is the output I get when I run it in GDB

(gdb) r
Starting program: C:\Users\Admin\Documents\Programming\asm\asm testing\main.exe
[New Thread 18312.0x3938]
[New Thread 18312.0x3550]
Hello!

Thread 1 received signal SIGSEGV, Segmentation fault.
0x00000000006514c0 in ?? ()
(gdb)

I am already following the calling convention defined by Microsoft here.

Marko Borković
  • 1,884
  • 1
  • 7
  • 22
  • 1
    No, you are not following the convention because you forgot to allocate the shadow space. You need to `sub rsp, 32` before the call and of course undo that e.g. by `mov rsp, rbp` in the epilogue. – Jester Dec 01 '21 at 23:18
  • @Jester, Does Windows need to zero `al` to tell varargs printf that there's no xmm arguments? – Erik Eidt Dec 02 '21 at 00:50
  • Don't think so. – Jester Dec 02 '21 at 00:57
  • 1
    The [Windows x64 calling convention](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170) makes no reference to zeroing al, but for varargs, it does say: *For floating-point values only, both the integer register and the floating-point register must contain the value, in case the callee expects the value in the integer registers.*. – David Wohlferd Dec 02 '21 at 02:22

0 Answers0