Here is a variadic function example, the VaFunc function calculates the sum of DWORDs.
.386
.model flat,stdcall
option casemap:none
ExitProcess PROTO :DWORD
printf PROTO C :DWORD,:VARARG
VaFunc PROTO C :DWORD,:VARARG
.data
f db 'Sum = %u',0
.data?
retaddr dd ?
i dd ?
.code
start:
push 7
push 6
push 5
push 3
call VaFunc
invoke printf,ADDR f,eax
invoke ExitProcess,0
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
VaFunc PROC C x:DWORD,y:VARARG
pop retaddr
pop edx
xor eax,eax
@@:
pop ecx
add eax,ecx
inc i
cmp edx,i
jne @b
push retaddr
retn
VaFunc ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
END start
Here is another version :
.386
.model flat,stdcall
option casemap:none
ExitProcess PROTO :DWORD
printf PROTO C :DWORD,:VARARG
VaFunc PROTO C :DWORD,:VARARG
.data
f db 'Sum = %u',0
.code
start:
invoke VaFunc,3,5,6,7
invoke printf,ADDR f,eax
invoke ExitProcess,0
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
VaFunc PROC C x:DWORD,y:VARARG
xor eax,eax
mov edx,DWORD PTR [esp+4]
@@:
add eax,DWORD PTR [esp+4*edx+4]
dec edx
jnz @b
retn
VaFunc ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
END start
Interesting code
Same with C
#include <stdio.h>
#include <stdarg.h>
int VaFunc(int, ...);
char f[] = "Sum = %u\n";
int __cdecl main(void)
{
printf(f, VaFunc(3,5,6,7));
return 0;
}
int VaFunc(int n, ...)
{
int sum = 0;
va_list args;
va_start(args, n);
for (int i = 0; i < n; i++)
sum += va_arg(args, int);
va_end(args);
return sum;
}
Hi Timo,
Thanks for your example. Here is another version eliminating the need of passing the number of parameters :
.386
.model flat,stdcall
option casemap:none
ExitProcess PROTO :DWORD
printf PROTO C :DWORD,:VARARG
VaFunc PROTO C :DWORD,:VARARG
.data
f db 'Sum = %u',0
.data?
t dd ?
.code
start:
mov t,esp
invoke VaFunc,5,6,7,10
invoke printf,ADDR f,eax
invoke ExitProcess,0
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
VaFunc PROC C x:DWORD,y:VARARG
xor eax,eax
lea edx,[esp+4]
@@:
add eax,DWORD PTR [edx]
add edx,4
cmp edx,t
jb @b
retn
VaFunc ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
END start
Simple printf emulator using only the bare percentage symbol to represent strings :
.386
.model flat,stdcall
option casemap:none
includelib \PellesC\lib\Win\kernel32.lib
includelib \PellesC\lib\Win\user32.lib
ExitProcess PROTO :DWORD
printfX PROTO C format:DWORD,args:VARARG
.data
format1 db 'This is a % % to % %',0
str1 db 'printfX',0
str2 db 'demo',0
str3 db 'type',0
str4 db 'strings.',0
.code
start:
invoke printfX,ADDR format1,
ADDR str1,ADDR str2,
ADDR str3,ADDR str4
invoke ExitProcess,0
END start