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.

Modules assemble into one program source/main.asm
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.

Call Win32 with the platform ABI source/main.asm
    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.

Walk the course in executable order source/main.asm
    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.

Write an array with a pointer loop source/main.asm
    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.