Examples of programs for various operating systems
This is a "Hello, world!" program for the DOS operating system. section.text org 0x100 mov ah, 0x9 mov dx, hello int 0x21 mov ax, 0x4c00 int 0x21 section.data hello: db 'Hello, world!', 13, 10, '$'
An equivalent program for Linux: global _start section.text _start: mov eax, 4 ; write mov ebx, 1 ; stdout mov ecx, msg mov edx, msg.len int 0x80 ; write; xor eax, msg.len ; invert return value from write xchg eax, ebx ; value for exit mov eax, 1 ; exit int 0x80 ; exit section.data msg: db "Hello, world!", 10 .len: equ $ - msg
An example of a similar program for Microsoft Windows: global _main extern _MessageBoxA@16 extern _ExitProcess@4 section code use32 class=code _main: push dword 0 ; UINT uType = MB_OK push dword title ; LPCSTR lpCaption push dword banner ; LPCSTR lpText push dword 0 ; HWND hWnd = NULL call _MessageBoxA@16 push dword 0 ; UINT uExitCode call _ExitProcess@4 section data use32 class=data banner: db 'Hello, world!', 0 title: db 'Hello', 0
Below is a 64-bit program for Apple OS X that inputs a keystroke and shows it on the screen global _start section.data query_string: db "Enter a character: " query_string_len: equ $ - query_string out_string: db "You have input: " out_string_len: equ $ - out_string section.bss in_char: resw 4 section.text _start: mov rax, 0x2000004 ; put the write-system-call-code into register rax mov rdi, 1 ; tell kernel to use stdout mov rsi, query_string ; rsi is where the kernel expects to find the address of the message mov rdx, query_string_len ; and rdx is where the kernel expects to find the length of the message syscall ; read in the character mov rax, 0x2000003 ; read system call mov rdi, 0 ; stdin mov rsi, in_char ; address for storage, declared in section.bss mov rdx, 2 ; get 2 bytes from the kernel's buffer syscall ; show user the output mov rax, 0x2000004 ; write system call mov rdi, 1 ; stdout mov rsi, out_string mov rdx, out_string_len syscall mov rax, 0x2000004 ; write system call mov rdi, 1 ; stdout mov rsi, in_char mov rdx, 2 ; the second byte is to apply the carriage return expected in the string syscall ; exit system call mov rax, 0x2000001 ; exit system call xor rdi, rdi syscall
Linking
NASM principally outputs object files, which are generally not executable by themselves. The only exception to this are flat binaries which are inherently limited in modern use. To translate the object files into executable programs, an appropriate linker must be used, such as the Visual Studio "LINK" utility for Windows or ld for Unix-like systems.
Development
The first release, version 0.90, was released in October 1996. On 28 November 2007, version 2.00 was released, adding support for x86-64 extensions. The development versions are not uploaded to SourceForge.net; instead, they are checked into Github with binary snapshots available from the project web page. A search engine for NASM documentation is also available. In July 2009, as of version 2.07, NASM was released under the Simplified BSD license. Previously, because NASM was licensed under LGPL, it led to development of Yasm, a complete rewrite of the NASM under the New BSD License. Yasm offered support for x86-64 earlier than NASM. It also added support for GNU Assembler syntax.
RDOFF
Relocatable Dynamic Object File Format is used by developers to test the integrity of NASM's object file output abilities. It is based heavily on the internal structure of NASM, essentially consisting of a header containing a serialization of the output driver function calls followed by an array of sections containing executable code or data. Tools for using the format, including a linker and loader, are included in the NASM distribution. Until version 0.90 was released in October 1996, NASM supported output of only flat-format executable files. In version 0.90, Simon Tatham added support for an object-file output interface, and for DOS.OBJ files for 16-bit code only. NASM thus lacked a 32-bit object format. To address this lack, and as an exercise to learn the object-file interface, developer Julian Hall put together the first version of RDOFF, which was released in NASM version 0.91. Since this initial version, there has been one major update to the RDOFF format, which added a record-length indicator on each header record, allowing programs to skip over records whose format they do not recognise, and support for multiple segments; RDOFF1 only supported three segments: text, data and bss.