Sample nasm programs
[Link] basic stand alone program
This program demonstrates basic text output to a screen. No "C" library functions are used. Calls are made to the operating system directly. (int 80 hex) ; ; ; ; ; ; [Link] assemble: link: run: output is: a first program for nasm for Linux, Intel, gcc nasm -f elf -l [Link] gcc -o hello hello.o hello Hello World ; ; ; ; [Link]
msg: len:
SECTION .data db "Hello World",10 equ $-msg SECTION .text global main mov mov mov mov int mov mov int edx,len ecx,msg ebx,1 eax,4 0x80 ebx,0 eax,1 0x80
data section the string to print, 10=cr "$" means "here" len is a value, not an address
main:
; code section ; make label available to linker ; standard gcc entry point ; ; ; ; ; arg3, length of string to print arg2, pointer to string arg1, where to write, screen write sysout command to int 80 hex interrupt 80 hex, call kernel
; exit code, 0=normal ; exit command to kernel ; interrupt 80 hex, call kernel
[Link] basic calling printf
This program demonstrates basic use of "C" library function printf. The equivalent "C" code is shown as comments in the assembly language. ; ; ; ; ; ; ; ; ; ; ; ; ; ; [Link] Assemble: Link: Run: Output: print an integer from storage and from a register nasm -f elf -l [Link] [Link] gcc -o printf1 printf1.o printf1 a=5, eax=7
Equivalent C code /* printf1.c print an int and an expression */ #include int main() { int a=5; printf("a=%d, eax=%d\n", a, a+2); return 0; }
; Declare some external functions ; extern printf ; the C function, to be called SECTION .data fmt: ; Data section, initialized variables
a: dd 5 ; int a=5; db "a=%d, eax=%d", 10, 0 ; The printf format, "\n",'0'
SECTION .text global main main: push mov mov add push push push call add mov pop mov ret ebp ebp,esp eax, [a] eax, 2 eax dword [a] dword fmt printf esp, 12 esp, ebp ebp eax,0
; Code section. ; the standard gcc entry point ; the program label for the entry point ; set up stack frame ; ; ; ; ; ; put a from store into register a+2 value of a+2 value of variable a address of ctrl string Call C function ; pop stack 3 push times 4 bytes
; takedown stack frame ; same as "leave" op ; normal, no error, return value ; return
[Link] more types with printf
This program demonstrates basic use of "C" library function printf. The equivalent "C" code is shown as comments in the assembly language. ; [Link] use "C" printf on char, string, int, double ; ; Assemble: nasm -f elf -l [Link] [Link] ; Link: gcc -o printf2 printf2.o ; Run: printf2 ; Output: ;Hello world: a string of length 7 1234567 6789ABCD 5.327000e-30 -1.234568E+302 ; ; A similar "C" program ; #include ; int main() ; { ; char char1='a'; /* sample character */ ; char str1[]="string"; /* sample string */ ; int int1=1234567; /* sample integer */ ; int hex1=0x6789ABCD; /* sample hexadecimal */ ; float flt1=5.327e-30; /* sample float */ ; double flt2=-123.4e300; /* sample double */ ; ; printf("Hello world: %c %s %d %X %e %E \n", /* format string for printf */ ; char1, str1, int1, hex1, flt1, flt2); ; return 0; ; } extern printf SECTION .data msg: ; the C function to be called ; Data section
db "Hello world: %c %s of length %d %d %X %e %E",10,0 ; format string for printf char1: db 'a' ; a character str1: db "string",0 ; a C string, "string" needs 0 len: equ $-str1 ; len has value, not an address inta1: dd 1234567 ; integer 1234567 hex1: dd 0x6789ABCD ; hex constant flt1: dd 5.327e-30 ; 32-bit floating point flt2: dq -123.456789e300 ; 64-bit floating point
SECTION .bss flttmp: resq 1 SECTION .text global main main: fld fstp push push push push push push push push push push call add mov ret dword [flt1] qword [flttmp] dword [flt2+4] dword [flt2] dword [flttmp+4] dword [flttmp] dword [hex1] dword [inta1] dword len dword str1 dword [char1] dword msg printf esp, 40 eax, 0 ; 64-bit temporary for printing flt1 ; Code section. ; "C" main program ; label, start of main program ; need to convert 32-bit to 64-bit ; floating load makes 80-bit, ; store as 64-bit ; push last argument first ; 64 bit floating point (bottom) ; 64 bit floating point (top) ; 64 bit floating point (bottom) ; 64 bit floating point (top) ; hex constant ; integer data pass by value ; constant pass by value ; "string" pass by reference ; 'a' ; address of format string ; Call C function ; pop stack 10*4 bytes ; exit code, 0=normal ; main returns to operating system
[Link] simple integer arithmetic
This program demonstrates basic integer arithmetic add, subtract, multiply and divide. The equivalent "C" code is shown as comments in the assembly language. ; [Link] show some simple C code and corresponding nasm code ; the nasm code is one sample, not unique ; ; compile: nasm -f elf -l [Link] [Link] ; link: gcc -o intarith intarith.o ; run: intarith ; ; the output from running [Link] and intarith.c is: ; c=5 , a=3, b=4, c=5 ; c=a+b, a=3, b=4, c=7 ; c=a-b, a=3, b=4, c=-1 ; c=a*b, a=3, b=4, c=12 ; c=c/a, a=3, b=4, c=4 ; ;The file intarith.c is: ; /* intarith.c */ ; #include ; int main() ; { ; int a=3, b=4, c; ; ; c=5; ; printf("%s, a=%d, b=%d, c=%d\n","c=5 ", a, b, c); ; c=a+b; ; printf("%s, a=%d, b=%d, c=%d\n","c=a+b", a, b, c); ; c=a-b; ; printf("%s, a=%d, b=%d, c=%d\n","c=a-b", a, b, c); ; c=a*b; ; printf("%s, a=%d, b=%d, c=%d\n","c=a*b", a, b, c);
; ; ; ; }
c=c/a; printf("%s, a=%d, b=%d, c=%d\n","c=c/a", a, b, c); return 0; extern printf ; the C function to be called ; a "simple" print macro ; %1 is first actual in macro call ; ; ; ; ; push onto stack backwards int c int b int a users string ; address of format string ; Call C function ; pop stack 5*4 bytes
%macro pabc 1 section .data .str db %1,0 section .text push push push push push call add %endmacro a: b: fmt: c: dword [c] dword [b] dword [a] dword .str dword fmt printf esp,20
section .data ; preset constants, writeable dd 3 ; 32-bit variable a initialized to 3 dd 4 ; 32-bit variable b initializes to 4 db "%s, a=%d, b=%d, c=%d",10,0; format string for printf section .bss resd 1 section .text global main ; unitialized space ; reserve a 32-bit word ; instructions, code segment ; for gcc standard linking ; label ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; c=5; 5 is a literal constant store into c invoke the print macro c=a+b; load a add b store into c invoke the print macro c=a-b; load a subtract b store into c invoke the print macro c=a*b; load a (must be eax for multiply) signed integer multiply by b store bottom half of product into c invoke the print macro c=c/a; load c load upper half of dividend with zero divide double register edx eax by a store quotient into c invoke the print macro
main: lit5:
mov mov pabc addb: mov add mov pabc mov sub mov pabc mov imul mov pabc mov mov idiv mov pabc mov ret
eax,5 [c],eax "c=5 " eax,[a] eax,[b] [c],eax "c=a+b" eax,[a] eax,[b] [c],eax "c=a-b" eax,[a] dword [b] [c],eax "c=a*b" eax,[c] edx,0 dword [a] [c],eax "c=c/a" eax,0
subb:
mulb:
diva:
; exit code, 0=normal ; main return to operating system
[Link] simple floating point arithmetic
This program demonstrates basic floating point add, subtract, multiply and divide. The equivalent "C" code is shown as comments in the assembly language. ; [Link] show some simple C code and corresponding nasm code ; the nasm code is one sample, not unique ; ; compile nasm -f elf -l [Link] [Link] ; link gcc -o fltarith fltarith.o ; run fltarith ; ; the output from running fltarith and fltarithc is: ; c=5.0, a=3.000000e+00, b=4.000000e+00, c=5.000000e+00 ; c=a+b, a=3.000000e+00, b=4.000000e+00, c=7.000000e+00 ; c=a-b, a=3.000000e+00, b=4.000000e+00, c=-1.000000e+00 ; c=a*b, a=3.000000e+00, b=4.000000e+00, c=1.200000e+01 ; c=c/a, a=3.000000e+00, b=4.000000e+00, c=4.000000e+00 ; ;The file fltarith.c is: ; #include ; int main() ; { ; double a=3.0, b=4.0, c; ; ; c=5.0; ; printf("%s, a=%e, b=%e, c=%e\n","c=5.0", a, b, c); ; c=a+b; ; printf("%s, a=%e, b=%e, c=%e\n","c=a+b", a, b, c); ; c=a-b; ; printf("%s, a=%e, b=%e, c=%e\n","c=a-b", a, b, c); ; c=a*b; ; printf("%s, a=%e, b=%e, c=%e\n","c=a*b", a, b, c); ; c=c/a; ; printf("%s, a=%e, b=%e, c=%e\n","c=c/a", a, b, c); ; return 0; ; } extern printf %macro pabc 1 section .data .str db %1,0 section .text push push push push push push push push call add %endmacro a: b: five: fmt: dword [c+4] dword [c] dword [b+4] dword [b] dword [a+4] dword [a] dword .str dword fmt printf esp,32 ; the C function to be called ; a "simple" print macro ; %1 is macro call first actual parameter ; ; ; ; ; ; ; ; push onto stack backwards double c (bottom) double c double b (bottom) double b double a (bottom) double a users string ; address of format string ; Call C function ; pop stack 8*4 bytes
section .data ; preset constants, writeable dq 3.333333333 ; 64-bit variable a initialized to 3.0 dq 4.444444444 ; 64-bit variable b initializes to 4.0 dq 5.0 ; constant 5.0 db "%s, a=%e, b=%e, c=%e",10,0; format string for printf
c:
section .bss resq 1 section .text global main
; unitialized space ; reserve a 64-bit word ; instructions, code segment ; for gcc standard linking ; label ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; c=5.0; 5.0 constant store into c invoke the print macro c=a+b; load a (pushed on flt pt stack, st0) floating add b (to st0) store into c (pop flt pt stack) invoke the print macro c=a-b; load a (pushed on flt pt stack, st0) floating subtract b (to st0) store into c (pop flt pt stack) invoke the print macro c=a*b; load a (pushed on flt pt stack, st0) floating multiply by b (to st0) store product into c (pop flt pt stack) invoke the print macro c=c/a; load c (pushed on flt pt stack, st0) floating divide by a (to st0) store quotient into c (pop flt pt stack) invoke the print macro
main: lit5:
fld fstp pabc addb: fld fadd fstp pabc fld fsub fstp pabc fld fmul fstp pabc fld fdiv fstp pabc mov ret
qword [five] qword [c] "c=5.0" qword [a] qword [b] qword [c] "c=a+b" qword [a] qword [b] qword [c] "c=a-b" qword [a] qword [b] qword [c] "c=a*b" qword [c] qword [a] qword [c] "c=c/a" eax,0
subb:
mulb:
diva:
; exit code, 0=normal ; main returns to operating system