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– requiresmainand linking withmsvcrXX.dll. These applications run in console windows; if you aren’t running an instance of cmd.exe, one will be opened./SUBSYSTEM:WINDOWS–WinMainis the starting point. See here. Usually in C, these#include <windows.h>and are linked directly tokernel32.dll. These a gui apps and are almost definitely linked withuser32.dlland possiblyadvapi32.dllas well./SUBSYSTEM:NATIVE– there are two types of application here; drivers and applications. Native NT apps run during windows startup and requireNtProcessSStartupas an entry point. There is no libc in native applications. Drivers are different again.A full list of supported windows subsystems by
link.exeis available here._startis the symbol windows will actually start your code running at. Normally,libcor the like actually handles_startand does some initial setup, so your program doesn’t actually quite start at_main. If you wanted to link withlibcyou 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:
I assume you’re not using the
-f elfone. 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 dosnasm -f coff.Edit 2 just to check, I assembled the code and disassembled it again. I also used mingw. Anyway, I got:
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:
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:
for each file you want to assemble. Substitute
win32forwin64when needed.ldwill do fine for linking.Just a thought – I never explained the
@16part. 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.