Hello!
If you just started with Win64,
then this example code might help you understand to more.
Main target, how to call function with more than four parameters, using macro or without.
Tested two linkers, Mingw64-GCC and GoLink, both worked fine.
.Formal_description:; ---------------------------------------------------------------------------
;
This is:
Win64 Basic Hello World NASM MINGW64 GoLink; Author: J.K. Encryptor256
; Date: October 22, 2013
; ---------------------------------------------------------------------------
;
Using:
;
;
1. The Netwide Assembler, NASM (
http://nasm.us/)
; The Netwide Assembler, NASM: It is an 80x86 and x86-64 assembler
; designed for portability and modularity.
;
;
2. Minimalist GNU for Windows, MinGW64 (
http://mingw-w64.sourceforge.net/)
; Mingw-w64: It delivers runtime, headers and libs for developing
; both, 64 bit (x64) and 32 bit (x86) windows applications, using GCC and
; other free software compilers.
;
; GCC is a part of MINGW64 toolset.
;
;
3. GoLink, (
http://www.godevtool.com/)
;
; ---------------------------------------------------------------------------
;
Description:
;
; Once upon a time...
; I did not found and was struggling with - printf, how to pass more than
; four arguments, where to put them and manage them correctly.
; So, i collected info, learned from all the place and builded my own example.
;
; ---------------------------------------------------------------------------
;
How to compile:
;
; Like this, in the way i did:
;
;
1. NASM: "nasm.exe helloworld.asm -f win64 -o helloworld.obj"
; Output obj size: 1016 bytes (1,016 bytes)
;
; Choose your linker:
;
;
2.1. GCC: "gcc.exe helloworld.obj -m64 -o helloworld.exe"
; Output exe size: 42.6 KB (43,697 bytes)
;
;
2.2. GoLink: "golink.exe /console /entry main helloworld.obj MSVCRT.dll"
; Output exe size: 2.00 KB (2,048 bytes)
;
; ---------------------------------------------------------------------------
.Example_code:; ---------------------------------------------------------------------------
; Tell compiler to generate 64 bit code
; ---------------------------------------------------------------------------
bits 64
; ---------------------------------------------------------------------------
; Data segment:
; ---------------------------------------------------------------------------
section .data use64
; Multiline printf format
txt_format: db 10,"==========================="
db 10,"Hello world:"
db 10,"==========================="
db 10,"param1: %u"
db 10,"param2: %I64u"
db 10,"param3: %f"
db 10,"param4: 0x%X"
db 10,"param5: %f"
db 10,"param6: 0x%I64X"
db 10,"===========================",10,0
align 16 ; Align txt_format data to 16 byte boundary
; Parameters:
param1: dq 0xFFFFFFFF
param2: dq 0xFFFFFFFFFFFFFFFF
param3: dq 29999.452
param4: dq 0xDEADBEEF ; Some other value
param5: dq 555595.5477
param6: dq 0xABBABABAABBABABA
; ---------------------------------------------------------------------------
; Code segment:
; ---------------------------------------------------------------------------
section .text use64
; ---------------------------------------------------------------------------
; Define macro: Invoke
; ---------------------------------------------------------------------------
%macro Invoke 1-*
%if %0 > 1
%rotate 1
mov rcx,qword %1
%rotate 1
%if %0 > 2
mov rdx,qword %1
%rotate 1
%if %0 > 3
mov r8,qword %1
%rotate 1
%if %0 > 4
mov r9,qword %1
%rotate 1
%if %0 > 5
%assign max %0-5
%assign i 32
%rep max
mov rax,qword %1
mov qword [rsp+i],rax
%assign i i+8
%rotate 1
%endrep
%endif
%endif
%endif
%endif
%endif
; ------------------------
; call %1 ; would be the same as this:
; -----------------------------------------
sub rsp,qword 8
mov qword [rsp],%%returnAddress
jmp %1
%%returnAddress:
; -----------------------------------------
%endmacro
; ---------------------------------------------------------------------------
; C management
; ---------------------------------------------------------------------------
global main
extern printf
main:
; -----------------------------------------------------------------------------
; Allocate stack memory
; -----------------------------------------------------------------------------
sub rsp,8*7
; Allocated 8*7 bytes:
; 8*4 from them are defaut parameters for all functions.
; 8*3 from them are those extra three parameters on stack.
; Total allocated space for seven parameters.
; 4x Default parameters are passed via registers.
; Those 3x extra parameters are passed via stack.
; !!! Always allocate stack space => odd number * 8,
; like now is just like we need => 8*7, doing like this will
; balance stack and make it aligned on 16 byte boundary.
; -----------------------------------------------------------------------------
; Call printf with seven parameters
; 4x of them are assigned to registers.
; 3x of them are assigned to stack spaces.
; -----------------------------------------------------------------------------
; Call printf with seven parameters
; -----------------------------------------------------------------------------
Invoke printf,txt_format,[param1],[param2],[param3],[param4],[param5],[param6]
; -----------------------------------------------------------------------------
; The same, BUT, without 'Invoke' macro would be like this:
; -----------------------------------------------------------------------------
; #3x# ; Stack parameters
mov rax,qword [param6]
mov qword [rsp+48],rax
mov rax,qword [param5]
mov qword [rsp+40],rax
mov rax,qword [param4]
mov qword [rsp+32],rax
; ---------------------------
; #4x# ; Register parameters
mov r9,qword [param3]
mov r8,qword [param2]
mov rdx,qword [param1]
mov rcx,qword txt_format
; ---------------------------
call printf
; ---------------------------
; -----------------------------------------------------------------------------
; Release stack memory
; -----------------------------------------------------------------------------
add rsp,8*7
; -----------------------------------------------------------------------------
; Quit
; -----------------------------------------------------------------------------
mov rax,qword 0
ret
; ----
; END ----
; ----
.Video:You can watch source code and runtime demo at youtube:
http://youtu.be/tWAYuOzlnvYVideo was recorded by "Win64 ScreenRecorder":
http://forum.nasm.us/index.php?topic=1749.0.Attachment:Attachment named: "win64_basic_helloworld_printf_console_nasm_mingw64_golink.zip",
which includes source file and already compiled obj and exe file.
And that's it,
Encryptor256!