Author Topic: Need help in dealing with "undefined reference to `_printf'" error  (Read 13092 times)

Offline nohemon

  • Jr. Member
  • *
  • Posts: 8
Need help in dealing with "undefined reference to `_printf'" error
« on: September 09, 2020, 10:51:10 PM »
This is my code:

Code: [Select]
    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?


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #1 on: September 11, 2020, 02:51:24 AM »
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


Offline Mathi

  • Jr. Member
  • *
  • Posts: 82
  • Country: in
    • Win32NASM
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #2 on: September 11, 2020, 03:09:49 PM »
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.

Code: [Select]
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   


Code: [Select]

;;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


Offline Mathi

  • Jr. Member
  • *
  • Posts: 82
  • Country: in
    • Win32NASM
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #3 on: September 11, 2020, 03:10:44 PM »
BTW

@Frank ,
        How are you ?  :)


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #4 on: September 11, 2020, 08:57:00 PM »
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


Offline nohemon

  • Jr. Member
  • *
  • Posts: 8
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #5 on: September 12, 2020, 12:25:15 AM »
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.

Code: [Select]
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   


Code: [Select]

;;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:

Code: [Select]
    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.



Offline nohemon

  • Jr. Member
  • *
  • Posts: 8
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #6 on: September 12, 2020, 12:29:00 AM »
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.

Offline Mathi

  • Jr. Member
  • *
  • Posts: 82
  • Country: in
    • Win32NASM
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #7 on: September 12, 2020, 06:23:49 AM »
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

I use the below tool chain. It works for both 32 bit and 64 bit.

https://sourceforge.net/projects/tdm-gcc/

Thanks,
Mathi.

Offline nohemon

  • Jr. Member
  • *
  • Posts: 8
Re: Need help in dealing with "undefined reference to `_printf'" error
« Reply #8 on: September 12, 2020, 10:09:31 AM »
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!