for learning purposes I wrote a small assembler program (test.asm):
global _main
extern _ExitProcess@4
section .text
_main:
mov ebx,0
push ebx
call _ExitProcess@4
Than I assembled it with NASM (test.obj):
nasm -f win32 test.asm
Now I am trying to link it to an "Portable Executable" (Windows 10 32 Bit):
ld test.obj
But I am always getting this error message:
undefined reference to `ExitProcess@4'
As far as I understand this message it means, that my program is not linked to "Kernel32.dll". But I thought "ld" is linking with "Kernel32.dll" automatically so I don't have to add some flags for that. Moreover if I add this flag:
ld test.obj -lkernel32
I am getting the following error message:
cannot find -lkernel32
I am sure I did a dumb mistake so maybe someone can tell me what's wrong.
EDIT:
If I am using "gcc" instead it work's:
gcc test.obj -nostdlib -lkernel32
So now I am wondering why "gcc" knows "-lkernel32" and "ld" not.
As you've already figured out, with ld
you'll need to specify the paths to find the proper libs.
One advice though, if you want to make your life easier on the learning process, there exists this lightweight linker called golink where linking these type of snippets is as easy as doing:
> nasm -f win32 foo.asm && golink foo.obj kernel32.dll
GoLink.Exe Version 1.0.2.3 - Copyright Jeremy Gordon 2002-2016 - JG@JGnet.co.uk
Output file: foo.exe
Format: Win32 Size: 1,536 bytes
It allows you to link to the necessary dlls and that's pretty much, don't need to mess up with search paths all the time.