I have the following code which assembles and runs fine on Windows XP 32 bit, 2.09.08 NASM:
; how to compile: nasm -f elf test.asm
; how to link: ld -o test.exe test.o
section .data
section .text
;global _WinMain@16
;_WinMain@16:
;global _start
_start:
mov ax,4
jmp $
According to many tutorials on NASM the asm file needs the following in it:
global _WinMain@16
_WinMain@16:
...
As you can see my asm file doesn't have that in it. (it's commented out, All it has is _start). So what is with all of these tutorials mentioning the need for the global _WinMain@16 stuff when my assembly program doesn't have that and works?
this is the command to assemble: nasm -f elf test.asm
this is the command to link: ld -o test.exe test.o
There are several types of application on Windows with different entry points depending on which type they are. By link.exe option:
/SUBSYSTEM:CONSOLE
- requires main
and linking with msvcrXX.dll
. These applications run in console windows; if you aren't running an instance of cmd.exe, one will be opened./SUBSYSTEM:WINDOWS
- WinMain
is the starting point. See here. Usually in C, these #include <windows.h>
and are linked directly to kernel32.dll
. These a gui apps and are almost definitely linked with user32.dll
and possibly advapi32.dll
as well./SUBSYSTEM:NATIVE
- there are two types of application here; drivers and applications. Native NT apps run during windows startup and require NtProcessSStartup
as an entry point. There is no libc in native applications. Drivers are different again.A full list of supported windows subsystems by link.exe
is available here.
_start
is the symbol windows will actually start your code running at. Normally, libc
or the like actually handles _start
and does some initial setup, so your program doesn't actually quite start at _main
. If you wanted to link with libc
you would have problems, since you'd have conflicting symbols with the libc library. If however you never intend to call any functions that are part of the C or C++ standard libraries, you are ok using _start
.
Edit yikes I've just noticed this:
; how to compile: nasm -f elf test.asm
; how to link: ld -o test.exe test.o
I assume you're not using the -f elf
one. ELF (executable and linkable format) is the linux format for executables; Windows requires Portable Executable (PE) images. The nasm option is -f win32
, or for dos nasm -f coff
.
Edit 2 just to check, I assembled the code and disassembled it again. I also used mingw. Anyway, I got:
SECTION .text align=16 execute ; section number 1, code
Entry_point:; Function begin
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 00401000 _ 66: B8, 0004
?_001: jmp ?_001 ; 00401004 _ EB, FE
; Entry_point End of function
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 00401006 _ 66: B8, 0004
?_002: jmp ?_002 ; 0040100A _ EB, FE
The rest of the header appears to be a valid PE format executable with no Entry point specification. I believe therefore that the code is simply "falling through" to the first piece of assembly code to start. I wouldn't advise this behaviour, especially when linking multiple objects as I've no idea what would happen. Do use -entry
.
Disassembling the elf object file I get this:
SECTION .data align=4 noexecute ; section number 1, data
SECTION .text align=16 execute ; section number 2, code
_start_here:; Local function
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 0000 _ 66: B8, 0004
?_001: jmp ?_001 ; 0004 _ EB, FE
_another_symbol:; Local function
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 0006 _ 66: B8, 0004
?_002: jmp ?_002
In other words, there aren't any specific ELF-format headers in it. I believe you're getting lucky on this one; start importing or trying to link with other code modules and things will start to get more tricky.
For Windows / mingw, you want:
nasm -f win32 file.asm
for each file you want to assemble. Substitute win32
for win64
when needed. ld
will do fine for linking.
Just a thought - I never explained the @16
part. The functions are 16-byte aligned on Windows, whereas, as you can see, the data is only four-byte aligned. See this explanation for the why.