NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: nohemon on September 09, 2020, 10:51:10 PM
-
This is my code:
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
I use nasm and gcc for compilation. I'm on a Windows 10 64-bit system.
I run nasm -f win64 source.asm. The .obj file is created with no errors.
Then I run gcc -m64 source.obj -o source.exe and I get these errors:
source.obj:source.asm:(.text+0x6): undefined reference to `_printf'
and
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/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x2e): undefined reference to `WinMain'
What am I missing?
-
Hi nohemon,
Welcome to the forum.
I can't help you much with this. I haven't run Windows since win98.
However... what you show is 32 bit code. Assemble/link it as 32 bit or change it to 64 bit. I hope a Windows user will help you!
Best,
Frank
-
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/ (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 (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
-
BTW
@Frank ,
How are you ? :)
-
Hi Mathi!
Thank you! Good to hear from you. I am old and tired, but in good health.
"main" and "printf" - without underscores - are for gnu C (Linux) too. Needed for 32 bit Windows. Watcom C wants "main_" and "printf_" etc. Go figure!
Nasm has "--prefix" and "--postfix" so we can add 'em from the command line...
Best,
Frank
-
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/ (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 (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 -lmingw32
This 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.
-
Hi Mathi!
Thank you! Good to hear from you. I am old and tired, but in good health.
"main" and "printf" - without underscores - are for gnu C (Linux) too. Needed for 32 bit Windows. Watcom C wants "main_" and "printf_" etc. Go figure!
Nasm has "--prefix" and "--postfix" so we can add 'em from the command line...
Best,
Frank
I see. I'm learning Assembly and that was kind of confusing. Thank you for clearing it out.
-
Hi Nohemon,
Check out the below link.
https://stackoverflow.com/questions/19690504/how-do-i-compile-and-link-a-32-bit-windows-executable-using-mingw-w64 (https://stackoverflow.com/questions/19690504/how-do-i-compile-and-link-a-32-bit-windows-executable-using-mingw-w64)
I use the below tool chain. It works for both 32 bit and 64 bit.
https://sourceforge.net/projects/tdm-gcc/ (https://sourceforge.net/projects/tdm-gcc/)
Thanks,
Mathi.
-
I finally compiled it and run it successfully in 32-bit. Thank you for your precious help.
Also, if you know any good book about Assembly for beginners which takes you step by step into hands-on examples, let me know please.
Either way, thanks both!