Hi nohemon,
You are trying to compile a 32 bit example with 64 bit assembler/linker switches
If you want the 32 bit version. Your version should work , with proper assemble and linking commands.
global _main
;;assemble with > nasm -fwin32 hello32.asm
;;Link with > gcc -m32 -mconsole hello32.obj -o hello32.exe
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
mov eax,0 ;;return code of our program
ret
message:
db 'Hello, World', 10, 0
If you intended to do this in 64 bit :
You may need to go through the below links for more info.
1)https://cs.lmu.edu/~ray/notes/nasmtutorial/
especially the 'Using Nasm in Windows' section. (Nice tutorial . Author might be in this forum)
2) x64 calling convention for Windows.
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019
1) What I noticed is that you need to lose the underscore (main instead of _main and printf instead of _printf) when linking with C libraries in 64 bit. (I dont' have a clear explanation for this).
2) for undefined reference to WinMain : you need to use console subsystem to tell the linker that this is a console application.
Link with : gcc -m64 -mconsole hello.obj -o hello.exe
;;64 bit version.
;;assemble with > nasm -fwin64 hello.asm
;; link with > gcc -m64 -mconsole hello.obj -o hello.exe
global main
extern printf
section .text
main:
;---------
push rbp
mov rbp, rsp
;; reserve for local variables
;; 2 qwords for argc and argv
;; and 1 qword for return value
;; 1 more qword to align with 16 bits
sub rsp, 8*4
mov rcx, message
call printf
mov rax,0
add rsp,8*4 ;; deallocate local variables
pop rbp
ret
;---------
message:
db 'Hello, World', 13, 10, 0
The 64-bit version works perfectly, thanks! Although this solves my problem, I would also like to understand why the 32-bit version still doesn't work.
Using again the original code:
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
mov eax,0 ;;return code of our program
ret
message:
db 'Hello, World', 10, 0
I run
nasm -fwin32 Source.asm && gcc -m32 -mconsole Source.obj -o output.exe which introduces me this errors:
C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe:
skipping incompatible C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/libmingw32.a
when searching for -lmingw32This also applies for
-lgcc, -lgcc_eh, -lmoldname and many more libraries. I searched this on google and these errors/warnings indicate that I'm trying to link 32-bit libraries with 64-bit linker, which is incompatible.
There is a 32-bit version of mingw, but the mingw 64-bit version also supports 32-bit. So, it's not about the linker (?).
I tried to use the link.exe, but then I get
LINK : fatal error LNK1561: entry point must be defined. I add a "global main" line at the begining, re-link, and get
error LNK2001: unresolved external symbol for _printf and _mainCRTStartup.
I can't think anything else.