Full program
The starter program that wires the chapters together and demonstrates Win32 output.
The entry point is deliberately small: include the lesson modules, print a greeting through Win32, call each chapter, run two compact data loops, and terminate cleanly.
Modules assemble into one program
MASM's include is source inclusion, not dynamic linking. Each guarded chapter becomes part of this translation unit and contributes its procedure.
include chapters/move.asm
include chapters/arith.asm
include chapters/flow.asm
include chapters/addr.asm
include chapters/strings.asm
include chapters/procs.asm
include chapters/macros.asm
include chapters/math.asm
Keep in mind: The header guards prevent an accidental second inclusion from defining the same symbols twice.
Call Win32 with the platform ABI
The program obtains the console output handle, places the first four WriteFile arguments in registers, writes the fifth in stack space, and calls the operating system.
mov rcx, std_output_handle ; output handle arg
call GetStdHandle ; get handle from os
; --- print hello ---
; note: how to calculate param stack location:
; nth parm - 1 = (5 - 1) * 8 = 32 bytes
; -----------------------------------------------------------------------------
mov rcx, rax ; [0] hFile
lea rdx, outputmessage ; [1] lpBuffer
mov r8, outputmessagelength ; [2] nNumberOfBytesToWrite
xor r9, r9 ; [3] lpNumberOfBytesWritten
mov [rsp + 32], r9 ; [4] lpOverlapped
call WriteFile ; print
Keep in mind: API calls are ordinary procedure calls once the arguments and stack obey the ABI.
Walk the course in executable order
Each lesson is also a procedure. Keeping the call list in learning order makes the repository useful both as a runnable program and as a table of contents.
call move
call arith
call flow
call addressing
call strings
call procs
call macros
call math
Keep in mind: Set a debugger breakpoint on one call and step into the chapter you are reading.
Write an array with a pointer loop
The loop stores the counter through rdx, advances the pointer by one dword, and branches until all N elements have been initialized.
xor rcx, rcx
lea rdx, arr
arr_loop:
mov dword ptr [rdx], ecx
inc ecx
add rdx, sizeof dword
cmp ecx, N
jl arr_loop
Keep in mind: The pointer advances in bytes; the loop count advances in elements.
Keep these rules
- The main module is wiring, not a second copy of every lesson.
- Win32 APIs follow the same x64 procedure contract as your own code.
- Small executable examples are easiest to inspect in a debugger.