From: Frank K. <fbk...@zy...> - 2009-05-05 05:16:14
|
oh...@co... wrote: > Hi, > > Can anyone tell me how to call Win32 printf from a Nasm program? > > I've been trying: > > mov eax, msg > push eax > call _printf > . > . > . > msg: db 'this is a test', 10, 0 > > and that seems to work, but the stack seems to be messed up after that, so i'm wondering if there needs to be a "pop eax" after the call? Probably. As you know, the usual API is stdcall - callee cleans up stack. But printf, or anything that takes a variable number of parameters really *can't* work that way... So you'll have to do it - "pop eax", or "add esp, 4", or "lea esp, [esp + 4]"... even in Windows. > Also, what other parameters can be used, e.g., can I provide printf with a format string, and if so, how? Well, here's an example for Linux... ; nasm -f elf hwso.asm ; ld -I/lib/ld-linux.so.2 -lc -s -o hwso hwso.o global _start extern printf section .text _start: fld qword [anumber] sub esp, 8 fstp qword [esp] push msg push fmt call printf add esp, 16 mov eax, 1 xor ebx, ebx int 80h ;section .data fmt db "%s%f", 10, 0 msg db "The answer is: ", 0 anumber dq 42.0 For Windows, you'll want an underscore on "_printf". Nasm will do that for ya - "nasm -f win32 --PREFIX _ myprog.asm" or so (puts an underscore on all "extern" or "global" variables). The "int 80h" won't work, of course - ExitProcess instead... Note that printf expects double precision floats for "%f"! (*not* a "Linux thing", AFAIK). (important to know, since printing floats is the only excuse for printf :) I don't know what the command line to the linker needs to be - "whatever you're using" should be okay. New Nasm feature: you can use "\n" and the like, if you enclose the string in "back apostrophes" '`' instead of ' or ". (under the ~ on my keyboard) format_string db `hello\n`, 0 Thanks for the question, Jim! First message I've been able to approve in ages! :) Best, Frank |