Create an exe file in assembly with NASM on 32-bit Windows
Solution 1
Download and install Mingw. Then put nasm in the Mingw bin
folder.
Create a folder in the bin
folder named Hello
. In this folder,
create a file named main.asm
with the following code:
extern _printf
global _main
section .data
msg: db "Hello, world!",10,0
section .text
_main:
push msg
call _printf
add esp,4
ret
Open the terminal from inside the folder and compile, first, to object code with nasm:
D:\MinGW\bin\Hello> ..\nasm -fwin32 main.asm
Second, call gcc to link:
D:\MinGW\bin\Hello> ..\gcc main.obj -o main.exe
Finally, test it:
D:\MinGW\bin\Hello> main.exe
Hello, world!
Solution 2
It's an old question but i wonder why no one has mentioned the solution with the standard windows link /subsystem:console /entry:_main main.obj
Solution 3
The OP gave some code that he got from a tutorial, and he assembled it with NASM. When he went to link the output into a Windows executable, he couldn't get it to work.
@Michael Petch noted in the comments on the question (top) that the tutorial source was designed for Linux - the code as given could never work for Windows. He went on to mention that the linker isn't provided by NASM: the OP needed to get it from Microsoft.
Mohit Swami
Updated on July 09, 2022Comments
-
Mohit Swami almost 2 years
I'm making a hello world program in assembly language with NASM on 32-bit Windows 7. My code is:
section .text global main ;must be declared for linker (ld) main: ;tells linker entry point mov edx,len ;message length mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data msg db 'Hello, world!', 0xa ;our dear string len equ $ - msg ;length of our dear string
I save this program as hello.asm. Next, I created hello.o with:
nasm -f elf hello.asm
Now I'm trying to create the exe file with this command:
ld -s -o hello hello.o
But now I receive this error:
ld is not recognized as an internal or external command, operable program or batch
Why am I getting this error, and how can I fix it?
-
Peter Cordes about 6 yearsSeems like a bad idea to call your process entry point
main
: normally that symbol marks a function that's called by CRT startup code. I'd recommend_start
or something, like Linux uses by default, unless your command line does link in the CRT code. -
Peter Cordes about 6 yearsAnyway, yes this is a good answer to the title question; people's search results might bring them here when they have asm source code that will work on Windows, unlike the OP's usage of the 32-bit Linux
int 0x80
ABI (which isn't available on Windows, not via cygwin and not even on the Linux on Windows subsystem; it's pure x86-64 without the IA32 compat ABI.) -
Aritro Shome over 2 yearswhy did you append 0 ? 10 was sufficient for newline AFAIK.
-
Cadoiz over 2 yearsYou can consider the standard windows
link /subsystem:console /entry:_main main.obj
as mentioned in this answer. -
ecm over 2 years@Aritro Shome:
printf
expects a zero terminated string so you should include an explicit zero-value byte. -
Aritro Shome over 2 years@ecm but when we use printf with C or C++ we don't explicitly include a zero value byte. Is it done by the compiler then ?
-
ecm over 2 years@Aritro Shome: Yes, It is done by the compiler. The assembler does not automatically add it though. You should explicitly add it. (In practice, it may happen that the next byte in the data section is a zero anyway, but it is better to explicitly include it.)