
Assembler Tutorial: Hello World with NASM and CL.EXE or LINK.EXE
Introduction
If learning assembler with the NASM.exe assembler peaks your interest, you might be interested in this extensive tutorial by Paul Carter. Annoyingly, finding a linker on Windows that plays nice with NASM took me a while. The tutorial by P. Carter is not very clear on this matter. I wanted to use the linker link.exe
that comes with Visual Studio 2010, because the free DJGPP linker that is mentioned by Mr Carter generates badly formatted .exe files. In this post I will show how to compile and link a Hello World assembler program with nasm.exe
and link.exe
.
Compiling Assembly Code
Let’s compile and link this Hello World program (courtesy of Ray Toal) in a file named helloworld.asm
.
; This is a Win32 console program that writes "Hello, World" on one line and ; then exits. It needs to be linked with a C library. global _main extern _printf section .text _main: push message call _printf add esp, 4 ret message: db 'Hello, World', 10, 0
As you can see we use the printf()
function to print the text “Hello, World”. This function is marked as extern
, because it is an imported function (it resides in the C Runtime Library).
The tutorial by Paul Carter provides a command for assembling example code in the file asm_io.asm
:
; To assemble for Microsoft Visual Studio ; nasm -f win32 -d COFF_TYPE asm_io.asm
Unfortunately, this syntax is incorrect. The -d
switch seems to be deprecated in my NASM version (2.09.04) : it does not do anything. The indicated filetype win32
does seem to be correct–it denotes the win32 object file format, which makes sense.
The correct command for compiling the helloworld.asm
file is:
nasm -f win32 helloworld.asm
With this command NASM generates a file called helloworld.obj
. Now we must use a linker to link the .obj
file into a .exe
file. Open the Visual Studio Command Prompt and type:
link.exe helloworld.obj libcmt.lib // or cl.exe helloworld.obj /link libcmt.lib
The printf()
function is statically included through libcmt.lib, which contains the C Runtime Library. You get an error if you omit it: error LNK2001: unresolved external symbol _printf
Now you can run helloworld.exe to test your program.
Further Info
- There are other ways to create an assembler program that prints to the screen: you can use the deprecated DOS API (using interrupts), or omit the C runtime library and directly call the Windows API. Read this stackoverflow thread for more info.
- If you use Microsoft’s MASM assembler solution in VS2010 (ml.exe) to create an object file, you can just call
link.exe helloworld.obj
without mentioninglibcmt.lib
. How is this possible? The.obj
file generated by MASM contains a.drective
section, which contains linker directives. These directives referencelibcmt.lib
, andlink.exe
includeslibcmt.lib
as a result. So the file is still included by the linker, but you don’t have to worry about it!
Hello Mr. Art0. Your tutorial is turned out to be very useful for me. I dug internet looking for usage of cl tool for two month, but could not find any precise tutorial. Microsoft’s official documentation do not describe matter properly.
Thank you.
With regards Fazliddin.
Great tutorial!!
Thank you!
My apologies for this very amateur question.
With win7 64 ultimate and Visual Studio 2010 (full package) installed, do I need to set a PATH to use cl.exe or link.exe with NASM from the command line?
Your help is greatly appreciated.
As you probably understand, if you want to call an EXE file without specifying its full path on the command line, then it has to be either in the current directory directory of cmd.exe, or the directory must be in the PATH environment variable.
If you use the Visual Studio Command Prompt then the PATH will automatically contain the location of cl.exe. However, to call nasm.exe from any directory as well, you are correct that you need to add it to the PATH variable manually. Restart cmd.exe afterwards, and use the set command to look at your current environment variables and check that it worked!
I Just Want To Say Thank You Very Much