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 #####