Previous Chapter | Contents | Index
These examples show how to use the NASMX macro system to create assembly programs.
It is recommended that you read the examples in order starting with the first example.
Each subsequent example builds upon the previous example.
Please note that, being examples, they are not optimized nor are errors checked for.
They are, however, working examples that you can build from.
Simply create a new working directory for each example and copy/paste the code into a new file within each directory.
Once you understand how these examples work you are ready to begin building the DEMOS for your system.
The DEMOS directories contain additional working examples that show some of the more advanced features of NASMX.
%include 'nasmx.inc'
IMPORT cdecl, printf
ENTRY my_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .text]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROC my_main
LOCALS NONE
INVOKE printf, message
ENDPROC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .data]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message: declare(NASMX_TCHAR) NASMX_TEXT('Hello, World!'),13,10,0
%include 'nasmx.inc'
IMPORT cdecl,printf
ENTRY my_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .text]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%define ODD_OR_EVEN 8
PROC my_main
LOCALS NONE
mov ecx, ODD_OR_EVEN
mov eax, ecx
and eax,1
IF eax,==,0
INVOKE printf, message, ecx, msgEven
ELSE
INVOKE printf, message, ecx, msgOdd
ENDIF
ENDPROC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .data]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message: declare(NASMX_TCHAR) NASMX_TEXT('%d is an %s number.'),13,10,0
msgOdd: declare(NASMX_TCHAR) NASMX_TEXT('ODD'),0
msgEven: declare(NASMX_TCHAR) NASMX_TEXT('EVEN'),0
%include 'nasmx.inc'
IMPORT cdecl,printf
ENTRY my_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .text]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%define LIMIT 100
PROC my_main
USES ebx
LOCALS NONE
mov ebx, LIMIT
WHILE ebx,!=, 0
mov ecx, ebx
mov eax, ebx
dec ebx
and eax,1
IF eax,==,0
CONTINUE
ENDIF
INVOKE printf, message, ecx
ENDWHILE
ENDPROC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .data]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message: declare(NASMX_TCHAR) NASMX_TEXT('%d is odd.'),13,10,0
%include 'nasmx.inc'
IMPORT cdecl,printf
PROTO my_pow2, uint32_t exp
ENTRY my_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .text]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%define EXPONENT 8
PROC my_pow2, uint32_t exp
LOCALS NONE
mov eax, 1
mov ecx, uint32_t [argv(.exp)]
WHILE ecx,!=,0
IF ecx,>,31
xor eax,eax ; return 0 to indicate error
BREAK ; break out of while loop
ENDIF
shl eax, 1
dec ecx
ENDWHILE
ENDPROC
PROC my_main
LOCALS
LOCAL result, unint32_t, 1
ENDLOCALS
INVOKE my_pow2, EXPONENT
IF eax,!=,0
mov uint32_t [var(.result)], eax
INVOKE printf, message, EXPONENT, uint32_t [var(.result)]
ELSE
INVOKE printf, errmsg
ENDIF
ENDPROC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .data]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message: declare(NASMX_TCHAR) NASMX_TEXT('The power of 2 to %u = %u'),13,10,0
errmsg: declare(NASMX_TCHAR) NASMX_TEXT('an error occurred!'),13,10,0
%include 'nasmx.inc'
NASMX_STRUC POINT
NASMX_RESERVE x, uint32_t, 1
NASMX_RESERVE y, uint32_t, 1
NASMX_ENDSTRUC
NASMX_STRUC RECT
NASMX_STRUC top_left, POINT
NASMX_RESERVE x, uint32_t, 1
NASMX_RESERVE y, uint32_t, 1
NASMX_ENDSTRUC
NASMX_STRUC bottom_right, POINT
NASMX_RESERVE x, uint32_t, 1
NASMX_RESERVE y, uint32_t, 1
NASMX_ENDSTRUC
NASMX_ENDSTRUC
IMPORT cdecl,printf
PROTO calc_area, ptrdiff_t rect
ENTRY my_main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .text]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROC calc_area, ptrdiff_t rect
USES ebx
LOCALS
LOCAL height, uint32_t, 1
LOCAL width, uint32_t, 1
ENDLOCALS
; get the pointer to the RECT structure
mov ebx, ptrdiff_t [argv(.rect)]
; calculate height
mov eax, uint32_t [ebx + RECT.bottom_right.y]
mov ecx, uint32_t [ebx + RECT.top_left.y]
sub eax, ecx
mov uint32_t [var(.height)], eax
; calculate width
mov eax, uint32_t [ebx + RECT.bottom_right.x]
mov ecx, uint32_t [ebx + RECT.top_left.x]
sub eax, ecx
mov uint32_t [var(.width)], eax
; area = width * height
xor edx, edx
mov ecx, uint32_t [var(.height)]
mul ecx ; return result in eax
ENDPROC
PROC my_main
LOCALS
LOCAL area, uint32_t, 1
ENDLOCALS
INVOKE calc_area, my_rect
mov uint32_t [var(.area)], eax
INVOKE printf, message, uint32_t [var(.area)]
ENDPROC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[section .data]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
message: declare(NASMX_TCHAR) NASMX_TEXT('area of rectangle = %d'),13,10,0
; instantiate a 20 x 20 rectangle
NASMX_ISTRUC my_rect, RECT
NASMX_AT top_left.x, 10
NASMX_AT top_left.y, 10
NASMX_AT bottom_right.x, 30
NASMX_AT bottom_right.y, 30
NASMX_IENDSTRUC
##### Makefile ##### NAME=MYDEMO AS=nasm ASFLAGS=-f elf32 LD=gcc LDFLAGS =-Wall -s LIBS =-lc # [ Suffixes ] # Change the suffixes to match your system environment O = .o ASM = .asm INC = .inc LST = .lst OBJS = $(NAME)$(O) all: $(NAME) $(NAME): $(OBJS) $(LD) $(LDFLAGS) -o $(NAME) $(OBJS) $(LIBS) $(NAME)$(O): $(NAME)$(ASM) $(AS) $(ASFLAGS) $(NAME)$(ASM) -o $(NAME)$(O) clean: rm *$(O) ./$(NAME) ##### End Makefile #####
##### Makefile ##### NAME=MYDEMO AS=nasm AFLAGS=-f win32 LD=GoLink LDFLAGS =/console /mix /entry _main LIBS =msvcrt.dll # [ Suffixes ] # Change the suffixes to match your system environment O = .obj X = .exe ASM = .asm INC = .inc LST = .lst # rules all: $(NAME)$(X) $(NAME)$(X): $(NAME)$(O) $(LD) $(LDFLAGS) $(NAME)$(O) $(LIBS) $(NAME)$(O): $(NAME)$(ASM) $(AS) $(AFLAGS) $(NAME)$(ASM) -o $(NAME)$(O) -l $(NAME)$(LST) clean: -del /f *.obj -del /f *.lst cleaner: -del /f *.bak -del /f *.lst -del /f *.obj -del /f *.exe ##### End Makefile #####