NASM - The Netwide Assembler

NASM Forum => Programming with NASM => Topic started by: Cu29p on February 14, 2016, 12:54:22 PM

Title: Windows 64 bit stack frame
Post by: Cu29p on February 14, 2016, 12:54:22 PM
I have a question about the stack frame because I'm pretty confused.
First the test program:
Code: [Select]
extern GetStdHandle
extern WriteFile
extern lstrlenA

section .bss

written resd 1
hstdout resq 1

section .data

num db 0, 13, 10, 0

section .text

global main

main:

MOV rcx, -11
CALL GetStdHandle
MOV [hstdout], rax

MOV cl, 48
MOV dl, 0
MOV r8b, 1
MOV r9b, 0
PUSH 1 ;rsp+16
PUSH 0 ;rsp+8
PUSH 2 ;rsp+0
CALL add7
MOV [num], al

ADD rsp, 24

MOV rcx, num
CALL cout

exit:
XOR rax, rax
RET

add7:
MOV rax, rcx
ADD rax, rdx
ADD rax, r8
ADD rax, r9
ADD rax, [rsp + 24]
ADD rax, [rsp + 16]
ADD rax, [rsp + 8]

RET

cout:
ENTER 24, 0

CALL lstrlenA

MOV rdx, rcx
MOV rcx, [hstdout]
MOV r8, rax
MOV r9, written
PUSH 0
CALL WriteFile

LEAVE

RET

So, in the main function I'm deallocating the 24 bytes I pushed on the stack for the test function add7. Now, why do I need to allocate 24 or more bytes in the cout function? The only thing I should need to do is to deallocate the last parameter (and to save rbp), but if I change anything there my program can't execute.

Someone please explain that to me
Title: Re: Windows 64 bit stack frame
Post by: Cu29p on February 16, 2016, 12:12:08 PM
Ok, I think I got it now:

Code: [Select]
cout:
SUB rsp, 40

PUSH rcx
CALL lstrlenA
POP rdx

MOV rcx, [hStdOut]
MOV r8d, eax
MOV r9, written
MOV qword [rsp + 32], 0
CALL WriteFile

ADD rsp, 40

RET

Allocating always 32 bytes for the win32 functions in case they want to save registers. If there are more than 4 arguments put them in the right spot on the stack and make sure there's enough space for them. enter, leave and the rbp thing is only necessary for debugging.