Reputation: 24612
I'm trying to build hello.asm into a Windows executable, but when I use the suggested commands for assembling, linking, and compiling the code, I get errors. Whether I'm using Strawberry Perl's GCC or MinGW's GCC, both give errors for the same YASM/NASM code.
Here are the traces. Either I'm doing something wrong in my Makefile or .ASM, or the linking process is buggy. Either way, I'd like someone to help me resolve the errors.
I get the same result whether I use nasm or yasm to assemble the object file.
Strawberry Perl GCC Trace:
C:\> make
nasm -f win32 -l hello.lst hello.asm
gcc -o hello hello.o
ld: cannot find crt1.o: No such file or directory
ld: cannot find -lmingw32
ld: cannot find -lgcc
ld: cannot find -lmoldname
ld: cannot find -lcrtdll
ld: cannot find -luser32
ld: cannot find -lkernel32
ld: cannot find -ladvapi32
ld: cannot find -lshell32
ld: cannot find -lmingw32
ld: cannot find -lgcc
ld: cannot find -lmoldname
ld: cannot find -lcrtdll
make: *** [hello] Error 1
MinGW GCC Trace:
$ make
gcc -o hello hello.o
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0x104): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
make: *** [hello] Error 1
Specs:
Upvotes: 0
Views: 5112
Reputation: 354
Replace your main()
function with label _WinMain@16
like this:
section .text
extern _foo
;--------------------------------------------------
; main()
; 在 Win32 環境下, _WinMain@16 為程式進入點
;--------------------------------------------------
global _WinMain@16
_WinMain@16:
; foo(2,3)
; 呼叫時, 參數為堆疊順序 (先進後出)
push DWORD 3 ; b=3
push DWORD 2 ; a=2
call _foo
; 堆疊復原
pop eax
pop eax
ret
#include <stdio.h>
void foo(int a, int b) {
printf("%d + %d = %d\n", a, b, a+b);
}
all:
rm -f *.o
gcc -c foo.c
nasm -f win32 -o main.o main.asm
gcc -o main.exe main.o foo.o
Upvotes: 4
Reputation: 24612
A solution in several parts:
A strange thing was happening: When I manually type gcc ...
to build the executables, I get few link errors. But when I used make
to run the exact same command, I got all kinds of link errors. It turns out that Free Pascal's make.exe was shadowing the proper make.exe. You can either fix this by promoting the proper directory in PATH, or uninstalling the offending application. I didn't have much use for Pascal, so I uninstalled it and suddenly gcc started working better.
Windows NASM/YASM assembly requires prefixing function names with underscore (_
). In order to keep the assembly code multiplatform, omit the underscores in the code, and use a Makefile option to tell nasm/yasm to prefix with an underscore when building in Windows.
Building with a manual ld
call to link the stuff together in Windows does not work. Substituting gcc
fixed the odd "undefined printf" link errors, because GCC somehow knows how to sort this out.
It's difficult to properly exit a program, espcially in a multiplatform way. One way is to set eax
to zero and then return.
All of this is reflected in working versions of hello.asm for NASM and YASM, at GitHub.
Upvotes: 1
Reputation: 5884
For a simple windows console hello: hello.asm
extern printf, ExitProcess
SECTION .data
szHello db "Hello there!", 0
SECTION .text
StartHello:
push szHello
call printf
add esp, 4
push 0
call ExitProcess
makefile:
hello: hello.obj
GoLink.exe /console /entry StartHello hello.obj kernel32.dll msvcrt.dll
hello.obj: hello.asm
nasm -f win32 hello.asm -o hello.obj
Upvotes: 0