2 ; Template for 32/64 bit dual mode assembly source files.
3 ; This file will contain both 32 and 64 bit versions of the functions.
4 ; Author: B.O. Love Nystrom.
6 ; Public License: BSD - No usage restrictions.
8 TITLE 32/64 bit assembly routines.
19 ;==============================================================================
20 ; Common x86/x64 - Constants and parameterless functions
21 ;==============================================================================
24 ; Your common code goes here..
27 ;==============================================================================
28 IF (_WIN64 eq 0) ; 32 bit version
29 ;==============================================================================
30 ECHO === 32-BIT ASSEMBLY (ML) ===
33 ; Argument passing: Right to left
34 ; Stack-maintenance: Calling function pops the stack
35 ; Name-decoration: Underscore character (_) is prefixed to names,
36 ; except when exporting __cdecl functions that use C linkage.
39 ; Argument-passing: Right to left. By value, unless pointer or reference.
40 ; Stack-maintenance: Called function pops the stack.
41 ; Name-decoration: An underscore (_) is prefixed to the name. The name is
42 ; followed by the at sign (@) followed by the number of bytes (in decimal)
43 ; in the argument list. In other words, a function declared as
44 ; int func( int a, double b ); is decorated as: _func@12
47 ; Argument-passing: The first two DWORD or smaller arguments are passed in
48 ; ECX and EDX registers; all other arguments are passed right to left.
49 ; Stack-maintenance: Called function pops the stack.
50 ; Name-decoration: At sign (@) is prefixed to names; an at sign followed by
51 ; the number of bytes (in decimal) in the parameter list is suffixed to names.
57 ; UINT32 __cdecl foo_c( UINT32 bar );
61 mov eax, [epb+8] ; first argument
64 ret ; Caller unstacks the args
69 ; UINT32 __stdcall foo_s( UINT32 bar );
73 mov eax, [epb+8] ; first argument
76 ret 4 ; Unstack the args
81 ; UINT32 __fastcall foo_f( UINT32 bar );
85 mov eax, ecx ; first argument
88 ret ; For 3 or more args, unstack all except the first two
93 ;==============================================================================
95 ;==============================================================================
96 ECHO === 64-BIT ASSEMBLY (ML64) ===
98 ; Extern C assembly routines does NOT get an added underscore with MSVC + ML64.
99 ; Hence the x64 assembly routines must be named _exactly_as_the_C_prototypes_,
100 ; or, in case of C++ class members, the mangled C++ identifiers.
102 ; Fastcall is used regardless of prototype declaration!
103 ; Arguments -> RCX, RDX, R8, R9, then stack.
105 ; The four register args are backed by unused stack cells.
106 ; Ergo, after std prologue the fifth argument is at [RBP+48].
108 ; Normal fastcall stack cleanup convention (function pop args) is *not used*.
109 ; Functions end with 'ret 0' even if they had stack args.
111 ; RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile.
112 ; RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are nonvolatile
113 ; and must be saved and restored by a function that use them.
115 ; frame$ = 10h ; Offset from rbp to first shadow arg after 'enter 0,0'
116 ; x64 fastcall arguments:
117 ; rcx = arg1 (rbp+10h)
118 ; rdx = arg2 (rbp+18h)
119 ; r8 = arg3 (rbp+20h)
120 ; r9 = arg4 (rbp+28h)
127 ; UINT64 foo( UINT64 bar );
130 ;enter 0,0 ;<< not needed if <= 4 args
131 mov rax, rcx ; first argument
133 ;leave ;>> not needed if <= 4 args
134 ret ; Caller balances the stack