I have this "Hello world!" program written in assembly (NASM syntax):
; hello.asm
global _start
extern GetStdHandle
extern WriteFile
section .text
_start:
push dword -11
call GetStdHandle
sub esp, 4
mov ebx, esp
push dword 0
push ebx
push message_length
push message
push eax
call WriteFile
add esp, 4
xor eax, eax
ret
section .data
message: db `Hello world!\r\n`
message_length equ $ - message
I tried linking the object file with MinGW's ld but I couldn't get it to work:
nasm -f win32 hello.asm -o hello.obj
ld -mi386pe hello.obj -o hello.exe -lkernel32
The output of ld is:
ld: cannot find -lkernel32
Trying to link the object file with GoLink results in a success:
nasm -f win32 hello.asm -o hello.obj
golink /entry _start /console hello.obj -o hello.exe kernel32.dll
The output of GoLink is:
GoLink.Exe Version 1.0.3.0 Copyright Jeremy Gordon 2002-2018 info@goprog.com
Output file: hello.exe
Format: Win32 Size: 2,048 bytes
And the program runs fine:
> hello
Hello world!
>
How do I link an object file using ld under Windows? Please note that I don't want to link to the CRT, since I'm not using it.
Here are my failed attempts, and their outputs:
> ld -mi386pe hello.obj -o hello.exe -lkernel32
ld: cannot find -lkernel32
> ld -mi386pe hello.obj -o hello.exe -LC:\Windows\System32 -lkernel32
ld: skipping incompatible C:\Windows\System32/kernel32.dll when searching for -lkernel32
ld: skipping incompatible C:\Windows\System32/kernel32.dll when searching for -lkernel32
ld: cannot find -lkernel32
> ld -mi386pe hello.obj -o hello.exe -LC:\Windows\SysWOW64 -lkernel32
ld: hello.obj:hello.asm:(.text+0x3): undefined reference to `GetStdHandle'
ld: hello.obj:hello.asm:(.text+0x18): undefined reference to `WriteFile'
Also, output if I decorate the names as _GetStdHandle@4 and _WriteFile@20:
> ld -mi386pe hello.obj -o hello.exe -LC:\Windows\SysWOW64 -lkernel32
ld: warning: resolving _GetStdHandle@4 by linking to _GetStdHandle
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
ld: warning: resolving _WriteFile@20 by linking to _WriteFile
> hello
Access is denied.
> rem This also gives a popup window which says "This app can't run on your PC"
> ld -mi386pe hello.obj -o hello.exe -LC:\Windows\SysWOW64 --disable-stdcall-fixup -lkernel32
ld: hello.obj:hello.asm:(.text+0x3): undefined reference to `GetStdHandle@4'
ld: hello.obj:hello.asm:(.text+0x18): undefined reference to `WriteFile@20'
> ld -mi386pe hello.obj -o hello.exe -LC:\Windows\SysWOW64 --enable-stdcall-fixup -lkernel32
> hello
Access is denied.
Also, output if I decorate the names as _GetStdHandle and _WriteFile:
> ld -mi386pe hello.obj -o hello.exe -LC:\Windows\SysWOW64 -lkernel32
> hello
Access is denied.
> rem It doesn't change if I add --enable-stdcall-fixup or --disable-stdcall-fixup
Platform details:
- Windows 10 x64
- nasm 2.14rc15
- ld 2.32
- gcc 9.2.0
- golink 1.0.3.0