nasm programming language

Learn from examples

1. Program to output a string, integer, and floating point exnl1.asm source code ;; exnl1.asm example print string, integer, float ;;; semicolon, one or more is comment ; sections contain specific information: ; section .data is for initialized variables, strings, arrays, etc. ; section .rodata is for initialized constants, protected, not changeable ; section .bss is block starting symbol for uninitialized arrays, etc. ; section .txt is last, for program instructions, define macros before use ; print using printf (everything same as C) extern printf ; the C function, to be called section .data ; Data section, initialized variables msg: db "nasm exnl1.asm running", 0 ; C string needs 0 msg2: db "exnl1.asm finished", 0 fmt: db "%s", 10, 0 ; The printf format, "\n",'0' string format i: dq 9999 ; integer as quad word fmti: db "i = %d", 10, 0 ; integer format x: dq 37.1 ; floating point as quad word fmtx: db "x = %f", 10, 0 ; floating point format section .text ; Code section. global main ; the standard gcc entry point main: ; the program label for the entry point push rbp ; set up stack frame, must be aligned ; print string mov rdi,fmt ; address of format, required register rdi mov rsi,msg ; address of data mov rax,0 ; or can be xor rax,rax call printf ; Call C function ; print integer mov rdi,fmti ; address of format, required register rdi mov rsi,[i] ; value of data mov rax,0 ; number of float to print call printf ; Call C function ; print float or double movq xmm0, qword[x] ; value of data mov rdi,fmtx ; address of format, required register rdi mov rax,1 ; number of float to print call printf ; Call C function mov rdi,fmt mov rsi,msg2 mov rax,0 call printf pop rbp ; restore stack mov rax,0 ; normal, no error, return value ret ; return Execution output: nasm exnl1.asm running i = 9999 x = 37.100000 exnl1.asm finished Many many registers available, see testreg_64.asm source code 2. commands to execute the source code at a minimum, Windows, Linux, MacOSX. Windows: use nmake or nasm.bat ??? exnl1.asm _main rather than main Linux: Assemble: nasm -f elf64 -l exnl1.lst exnl1.asm Link: gcc -m64 -o exnl1 exnl1.o Run: exnl1 > exnl1.out Output: cat exnl1.out Clean: rm -f exnl1.o MacOSX ??? exnl1.asm _main rather than main Sample Makefile: # Makefile for nasm exnl1.out file all: exnl1.out # can have many .out exnl1.out : exnl1.asm nasm -f elf64 -l exnl1.lst exnl1.asm # must use tab gcc -m64 -o exnl1 exnl1.o exnl1 > exnl1.out cat exnl1.out rm -f exnl1.o # optional exnl1.lst exnl1 3. You must be able to declare variables and arrays and matrix of various types. exnl3.asm source code ; exnl3.asm example declare variables, arrays, matrix extern printf section .data ; Data section, initialized variables msg: db "nasm exnl3.asm running", 0 ; C string needs 0 msg2: db "exnl3.asm finished", 0 fmt: db "%s", 10, 0 i1: db 1 ; byte, 8 bit, integer 1 i2: dw 2 ; word, 16 bit, integer 2 j3: dd 3, 3.5 ; double word, 32 bit, integer 3, float 3.5 f4: dq 1.1, 1.2, 2.1, 2.2 ; quad word, 64 bit, double 1.1, 1.2, 2.1, 2.2 i3: dq 1, 2, 3 ; quad word, 64 bit, long integers 1, 2, 3 ; quad word is 8 bytes (for indexing address) section .rodata ; read only data, protected one: dq 1.0 ; can not be changed section .bss ; block starting symbol for arrays s1: resb 80 ; 80 characters, bytes, allocated b2: resw 2 ; 2 words allocated c5: resd 5 ; 5 double words allocated a1: resq 3 ; 3 quad words allocated m1: resq 4 ; 4 quad words, could be 2 by 2 integer matrix ; increment byte address by 4 for each integer dmat: resq 8 ; could be 2 by 2 matrix of double ; increment byte address by 8 for each double section .text ; Code section. global main ; main program required name "main" main: push rbp ; set up stack frame, must be aligned mov rdi,fmt ; address of format, required register rdi mov rsi,msg ; address of data mov rax,0 ; or can be xor rax,rax call printf ; Call C function mov rdi,fmt ; finished print statement mov rsi,msg2 mov rax,0 call printf pop rbp ; restore stack mov rax,0 ; normal, no error, return value ret ; return Execution output: nasm exnl3.asm running exnl3.asm finished 3a. more sample code to see other examples: testreg_64.asm see available registers intarith_64.asm see integer operations intarith_64.out output fltarith_64.asm see float operations fltarith_64.out output 4. You need to be able to have loops, iteration statements exnl4.asm source code ; exnl4.asm example loops iteration extern printf section .data ; Data section, initialized variables msg: db "nasm exnl4.asm running", 0 ; C string needs 0 msg2: db "exnl4.asm finished", 0 fmt: db "%s", 10, 0 fmt1: db "iloop i=%d", 10, 0 ; format needs \n 0 n: dq 3 ; for simple loop fmtfl: db "floop x=%e", 10, 0 xlast: dq 8.0 ; for float loop xinc: dq 2.0 ; for +2.0 m1: dq 1.1, 1.2, 1.3, 2.1, 2.2, 2.3 ; row major 2 by 3 matrix m1name: db "m1", 0 ncol1: dq 2 nrow1: dq 3 m2: dq 1.1, 2.1, 3.1, 1.2, 2.2, 3.2 ; coloum major 3 by 2 matrix m2name: db "m2", 0 ncol2: dq 3 nrow2: dq 2 i8: dq 8 fmtm: db "%s[%d][%d]=%e", 10, 0 fijk: db "i=%d, j=%d, k=%d, l=%d", 10, 0 section .bss i: resq 1 ; reserve space, 1 is one quad word j: resq 1 k: resq 1 l: resq 1 x: resq 1 ; float type or any type section .text ; Code section. global main main: push rbp ; set up stack frame, must be aligned mov rdi,fmt ; address of format, required register rdi mov rsi,msg ; address of data mov rax,0 ; or can be xor rax,rax call printf ; Call C function ; simple loop mov rax,0 ; for(i=0 ; i<n; i++) mov [i],rax ; i=0 loop: ; use i for what you want mov rdi,fmt1 ; just print i mov rsi,[i] mov rax,0 call printf mov rax,[i] ; safest to keep variable in memory inc rax ; i++ mov [i],rax cmp rax,[n] ; i<n jne loop ; float loop fld qword [xinc] ; for(x=2.0 x<xlast x=x+xinc) fstp qword [x] ; x=2.0 floop: ; use x for what you want mov rdi,fmtfl ; just print x movq xmm0, qword [x] mov rax,1 call printf fld qword [x] ; safest to keep variable in memory fadd qword [xinc] ; x = x + xinc fstp qword [x] fld qword [xlast] ; pushed into st0, then st1 fld qword [x] ; pushed into st0 fcompp ; compare and pop both ; jg floop ; infinite loop jl floop ; quit first time ; for(i=0; i<nrow; i++) { for(j=0; j<ncol; j++) { print m1[i][j] }} mov rax,0 mov [i],rax ; i=0 loopi: mov rax,[i] mov rbx,0 mov [j],rbx ; j=0 loopj: mov rax,[i] mov rbx,[j] imul qword [ncol1] ; i*ncol1 add rax, rbx ; i*ncol1+j [i][j] mov [k],rax imul qword [i8] ; byte address offset mov [l],rax ; save to memory mov rdi,fijk ; debug print mov rsi,[i] mov rdx,[j] mov rcx,[k] mov r8,[l] mov rax,0 call printf mov rdi,fmtm ; print matrix mov rsi,m1name mov rdx,[i] mov rcx,[j] mov rbx,[l] ; set up byte offset movq xmm0,qword[m1+rbx] ; m1[(i*ncol1+j)*8] byte address mov rax,1 ; number of floats to print call printf mov rbx,[j] inc rbx ; j++ mov [j],rbx cmp rbx,[ncol1] ; j<ncol jne loopj mov rax,[i] inc rax ; i++ mov [i],rax cmp rax,[nrow1] ; i<nrow1 jne loopi mov rdi,fmt ; exit print mov rsi,msg2 mov rax,0 call printf pop rbp ; restore stack mov rax,0 ; normal, no error, return value ret ; return Execution output: nasm exnl4.asm running iloop i=0 iloop i=1 iloop i=2 floop x=2.000000e+00 i=0, j=0, k=0, l=0 m1[0][0]=1.100000e+00 i=0, j=1, k=1, l=8 m1[0][1]=1.200000e+00 i=1, j=0, k=2, l=16 m1[1][0]=1.300000e+00 i=1, j=1, k=3, l=24 m1[1][1]=2.100000e+00 i=2, j=0, k=4, l=32 m1[2][0]=2.200000e+00 i=2, j=1, k=5, l=40 m1[2][1]=2.300000e+00 exnl4.asm finished 5. You need if then else conditional statements exnl5.asm source code # exnl5.asm example of if then else ; exnl5.asm example if then else extern printf section .data ; Data section, initialized variables msg: db "nasm exnl5.asm running", 0 ; C string needs 0 msg2: db "exnl5.asm finished", 0 msg3: db "if then else on integers", 0 msg4: db "if then else on floats", 0 fmt: db "%s", 10, 0 a: dq 1 b: dq 2 c: dq 3 xyz: dq 4 fmt1: db "true a < b ",10,0 fmt2: db "wrong on a < b ",10,0 fmt3: db "wrong on b > c ",10,0 fmt4: db "false b > c ",10,0 fmt5: db "failed 4==xyz ",10,0 fmt6: db "passed 4==xyz ",10,0 fmt7: db "failed 5>xyz ",10,0 fmt8: db "passed 5>xyz ",10,0 fmt9: db "failed 3<xyz ",10,0 fmt10: db "passed 3<xyz ",10,0 af: dt 1.0 bf: dt 2.0 cf: dt 3.0 fmt1f: db "true af < bf ",10,0 fmt2f: db "wrong on af < bf ",10,0 fmt3f: db "wrong on bf > cf ",10,0 fmt4f: db "false bf > cf ",10,0 section .bss ; unused, except to pop t: rest 1 ; reserve one space for dt section .text ; Code section. global main main: push rbp ; set up stack frame, must be aligned mov rdi,fmt ; address of format, required register rdi mov rsi,msg ; address of data mov rax,0 ; or can be xor rax,rax call printf ; Call C function mov rdi,fmt ; address of format, required register rdi mov rsi,msg3 ; mov rax,0 ; call printf ; ; code ifint_64.c for nasm ; /* ifint_64.c an 'if' statement that will be coded for nasm */ ; #include <stdio.h> ; int main() ; { ; long int a=1; ; long int b=2; ; long int c=3; ; long int xyz=4; ; if(a<b) ; printf("true a < b \n"); ; else ; printf("wrong on a < b \n"); ; if(b>c) ; printf("wrong on b > c \n"); ; else ; printf("false b > c \n"); ; ; if(4==xyz) goto label1e; ; printf("failed 4==xyz\n"); ;label1e: printf("passed 4==xyz\n"); ; ; if(5>xyz) goto label1g; ; printf("failed 5>xyz\n"); ;label1g: printf("passed 5>xyz\n"); ; ; if(3<xyz) goto label1l; ; printf("failed 3<xyz\n"); ;label1l: printf("passed 3<xyz\n"); ; ; return 0; ;} ; result of executing both "C" and assembly is: ; true a < b ; false b > c mov rax,[a] ; a cmp rax,[b] ; compare a to b jge false1 ; choose jump to false part ; a < b sign is set mov rdi, fmt1 ; printf("true a < b \n"); mov rax,0 call printf jmp exit1 ; jump over false part false1: ; a < b is false mov rdi, fmt2 ; printf("wrong on a < b \n"); mov rax,0 call printf exit1: ; finished 'if' statement mov rax,[b] ; b cmp rax,[c] ; compare b to c jle false2 ; choose jump to false part ; b > c sign is not set mov rdi, fmt3 ; printf("wrong on b > c \n"); mov rax,0 call printf jmp exit2 ; jump over false part false2: ; b > c is false mov rdi, fmt4 ; printf("false b > c \n"); mov rax,0 call printf exit2: ; finished 'if' statement mov rax,4 cmp rax,[xyz] ; if(4==xyz) goto label1e; je label1e mov rdi, fmt5 mov rax,0 call printf label1e:mov rdi, fmt6 mov rax,0 call printf mov rax,5 cmp rax,[xyz] ; if(5>xyz) goto label1g; jg label1g mov rdi, fmt7 mov rax,0 call printf label1g:mov rdi, fmt8 mov rax,0 call printf mov rax,3 cmp rax,[xyz] ; if(3<xyz) goto label1l; jl label1l mov rdi, fmt9 mov rax,0 call printf label1l:mov rdi, fmt10 mov rax,0 call printf mov rdi,fmt ; address of format, required register rdi mov rsi,msg4 ; mov rax,0 ; call printf ; ; code ifflt_64.c for nasm ; /* ifflt_64.c an 'if' statement that will be coded for nasm */ ; #include <stdio.h> ; int main() ; { ; double af=1.0; ; double bf=2.0; ; double cf=3.0; ; if(af<bf) ; printf("true af < bf \n"); ; else ; printf("wrong on af < bf \n"); ; if(b>c) ; printf("wrong on bf > cf \n"); ; else ; printf("false bf > cf \n"); ; return 0; ;} ; result of executing both "C" and assembly is: ; true af < bf ; false bf > cf fld tword [bf] ; bf into st0 fld tword [af] ; af into st0, pushes b into st1 fcompp ; compare and pop both ; fcomip st0,st1 ; compare af to bf, pop af ; fstp tword [t] ; just to pop bf jl false1f ; choose jump to false part ; af < bf sign is set mov rdi, fmt1f ; printf("true af < bf \n"); mov rax, 0 call printf jmp exit1f ; jump over false part false1f: ; af < bf is false mov rdi, fmt2f ; printf("wrong on af < bf \n"); mov rax, 0 call printf exit1f: ; finished 'if' statement fld tword [cf] ; cf into st0 fld tword [bf] ; bf into st0, pushes cf into st1 fcompp ; compare and pop both ; fcomip st0,st1 ; compare bf to cf, pop bf ; fstp tword [t] ; just to pop cf jg false2f ; choose jump to false part ; bf > cf sign is not set mov rdi, fmt3f ; printf("wrong on bf > cf \n"); mov rax, 0 call printf jmp exit2f ; jump over false part false2f: ; bf > cf is false mov rdi, fmt4f ; printf("false bf > cf \n"); mov rax, 0 call printf exit2f: ; finished 'if' statement mov rdi,fmt ; print finished mov rsi,msg2 mov rax,0 call printf pop rbp ; restore stack mov rax,0 ; normal, no error, return value ret ; return Execution output: nasm exnl5.asm running if then else on integers true a < b false b > c passed 4==xyz passed 5>xyz passed 3<xyz if then else on floats true af < bf false bf > cf exnl5.asm finished 6. You need to be able to create functions, procedures, subroutines. exnl6.asm source code ; exnl6.asm example declare and call funstions and procedures extern printf section .data ; Data section, initialized variables msg: db "nasm exnl6.asm running", 0 ; C string needs 0 msg2: db "exnl6.asm finished", 0 fmt: db "%s", 10, 0 fmti db "diff = %d", 10, 0 fmtf: db "ssq = %f", 10, 0 af: dq 1.1 bf: dq 3.3 ai: dq 13 bi: dq 27 section .bss ; variable and array section cf: resq 1 ci: resq 1 tmp: resq 1 section .text ; Code section. global main main: push rbp ; set up stack frame, must be aligned mov rdi,fmt ; address of format, required register rdi mov rsi,msg ; address of data mov rax,0 ; or can be xor rax,rax call printf ; Call C function call jprt ; call no parameter procedure mov rdi,[ai] ; first integer parameter value mov rsi,[bi] ; second integer paramenter value call diff ; function return in rax mov [tmp],rax ; save result and print result using macro ; print mov rdi, fmti ; address of format string mov rsi, [tmp] ; int value mov rax, 0 ; 0 floating point arguments to printf call printf ; Call C function movq xmm0, qword[af] ; first double parameter value movq xmm1, qword[bf] ; second double parameter value call ssq ; function return in xmm2 movq qword[tmp], xmm2 ; save result and print result ; print mov rdi, fmtf ; address of format string movq xmm0, qword[tmp] ; first floating point in fmt mov rax, 1 ; 1 floating point arguments to printf call printf ; Call C function mov rdi,fmt mov rsi,msg2 mov rax,0 call printf pop rbp ; restore stack mov rax,0 ; normal, no error, return value ret ; return ; function definitions, called above section .data ; Data section jprthi: db "Hi from jprt", 10, 0 section .bss ; variables, arrays space tmpf: resq 1 ; temp space parf1: resq 1 parf2: resq 1 section .text ; Code section. jprt: mov rdi,fmt ; no parameters mov rsi,jprthi mov rax,0 call printf ret ; end jprt diff: mov rax,rdi ; rdi first integer parameter sub rax,rsi ; rsi second integer parameter ret ; function result in rax ssq: movq qword[parf1], xmm0 ; save first parameter movq qword[parf1], xmm1 ; save second parameter fld qword[parf1] ; first parameter fmul qword[parf1] ; squared fstp qword[tmpf] ; saved fld qword[parf2] ; second parameter fmul qword[parf1] ; squared fadd qword[tmpf] ; sum fstp qword[tmpf] ; return value movq xmm2, qword[tmpf] ; return in register ret Execution output: nasm exnl6.asm running Hi from jprt diff = -14 ssq = 10.890000 exnl6.asm finished 7. You need to be able to read and write files in various formats. exnl7.asm source code ;; exnl7.asm 32 bit read and print file ;; Test _read and _write system calls windows, read, write linux ;; removed _ for linux ;; ;; nasm -f elf -Wall -Werror exnl7.asm ;; gcc -m32 -o exnl7 exnl7.o ;; exnl7 < exnl7file.txt > exnl7.out ;; cat exnl7.out section .data prompt db 'Enter a string: ',0 prompt_len equ $ - prompt BUFSZ equ 1024 STDIN equ 0 STDOUT equ 1 section .bss buffer resb BUFSZ section .text global main extern read, write main: push prompt_len push prompt push STDOUT call write ; terminal or > file add esp, 12 push BUFSZ - 1 ; leave space for terminating 0 push buffer push STDIN ; command line or < file call read add esp, 12 push eax ; _read returns string length in eax push buffer push STDOUT call write add esp, 12 mov eax, 0 ret Execution output: Enter a string: line 1 of exnl7file.txt line 2 last line 8. You need to be able to use a number of files combined to build a program. This may include packages, libraries, operating system commands, header files, etc. exnl8f.asm functions source code ; exnl8f.asm example call functions and procedures in another file extern printf global jprt global diff global ssq ; function definitions, called in exnl8.asm section .data ; Data section jprthi: db "Hi from jprt", 10, 0 fmt: db "%s", 10, 0 section .bss ; variables, arrays space tmpf: resq 1 ; temp space parf1: resq 1 parf2: resq 1 section .text ; Code section. jprt: mov rdi,fmt ; no parameters mov rsi,jprthi mov rax,0 call printf ret ; end jprt diff: mov rax,rdi ; rdi first integer parameter sub rax,rsi ; rsi second integer parameter ret ; function result in rax ssq: movq qword[parf1], xmm0 ; save first parameter movq qword[parf1], xmm1 ; save second parameter fld qword[parf1] ; first parameter fmul qword[parf1] ; squared fstp qword[tmpf] ; saved fld qword[parf2] ; second parameter fmul qword[parf1] ; squared fadd qword[tmpf] ; sum fstp qword[tmpf] ; return value movq xmm2, qword[tmpf] ; return in register ret exnl8.asm source code ; exnl8.asm example call funstions and procedures in another file extern printf extern jprt ; in exnl8f.asm extern diff extern ssq section .data ; Data section, initialized variables msg: db "nasm exnl8.asm running", 0 ; C string needs 0 msg2: db "exnl8.asm finished", 0 fmt: db "%s", 10, 0 fmti db "diff = %d", 10, 0 fmtf: db "ssq = %f", 10, 0 af: dq 1.1 bf: dq 3.3 ai: dq 13 bi: dq 27 section .bss ; variable and array section cf: resq 1 ci: resq 1 tmp: resq 1 section .text ; Code section. global main main: push rbp ; set up stack frame, must be aligned mov rdi,fmt ; address of format, required register rdi mov rsi,msg ; address of data mov rax,0 ; or can be xor rax,rax call printf ; Call C function call jprt ; call no parameter procedure mov rdi,[ai] ; first integer parameter value mov rsi,[bi] ; second integer paramenter value call diff ; function return in rax mov [tmp],rax ; save result and print result using macro ; print mov rdi, fmti ; address of format string mov rsi, [tmp] ; int value mov rax, 0 ; 0 floating point arguments to printf call printf ; Call C function movq xmm0, qword[af] ; first double parameter value movq xmm1, qword[bf] ; second double parameter value call ssq ; function return in xmm2 movq qword[tmp], xmm2 ; save result and print result ; print mov rdi, fmtf ; address of format string movq xmm0, qword[tmp] ; first floating point in fmt mov rax, 1 ; 1 floating point arguments to printf call printf ; Call C function mov rdi,fmt mov rsi,msg2 mov rax,0 call printf pop rbp ; restore stack mov rax,0 ; normal, no error, return value ret ; return ; function definitions in file exnl8f.asm Makefile: exnl8.out : exnl8.asm exnl8f.asm nasm -f elf64 -l exnl8f.lst exnl8f.asm # must use tabs nasm -f elf64 -l exnl8.lst exnl8.asm gcc -m64 -o exnl8 exnl8.o exnl8f.o exnl8 > exnl8.out cat exnl8.out Execution output: nasm exnl8.asm running Hi from jprt diff = -14 ssq = 10.890000 exnl8.asm finished

Last updated 8/12/2019