Lesson 28 of 48 intermediate

Assembler Directives, Labels, and Macros

Control how the assembler builds your program — directives are instructions to the tool, not the CPU

Open interactive version (quiz + challenge)

Real-world analogy

Assembler directives are like stage directions in a theater script. The actors (CPU) never see them — they only follow dialogue and actions (instructions). But the director (assembler) uses stage directions to set the scene (ORG), assign roles (SEGMENT), place props (DB, DW), and create shortcuts (MACRO). Without stage directions, actors would not know where to stand.

What is it?

Assembler directives are commands that control the assembler tool itself rather than generating CPU instructions. They define data (DB, DW, DD), create constants (EQU), set memory origins (ORG), organize segments (SEGMENT/ENDS, ASSUME), name procedures (PROC/ENDP), and create code templates (MACRO/ENDM). Labels mark locations in code and data for reference by instructions and other directives.

Real-world relevance

Every real assembly program uses directives extensively. BIOS source code uses SEGMENT directives to map ROM regions. DOS programs use ORG 100h for COM files. Kernel bootloaders define data structures with DB/DW. Device driver developers use MACROs to wrap port I/O patterns. EQU constants name hardware register addresses for readability.

Key points

Code example

; Program: Demonstrate key directives and macros
; Uses: DB, DW, EQU, MACRO, PROC, labels

; --- Macro Definitions ---
print_str MACRO string_addr
  LEA DX, string_addr
  MOV AH, 09h
  INT 21h
ENDM

newline MACRO
  MOV AH, 02h
  MOV DL, 0Dh
  INT 21h
  MOV DL, 0Ah
  INT 21h
ENDM

; --- Constants ---
DOS_PRINT EQU 09h
DOS_EXIT  EQU 4Ch
MAX_ITEMS EQU 5

.MODEL SMALL
.STACK 100h
.DATA
  title_msg DB 'Directive Demo', 0Dh, 0Ah, '$'
  items     DB MAX_ITEMS DUP(0)    ; 5 zero bytes
  count     DW 0
  separator DB '---', 0Dh, 0Ah, '$'

.CODE
MAIN PROC
  MOV AX, @DATA
  MOV DS, AX

  print_str title_msg     ; macro expands inline
  print_str separator

  ; Initialize items array
  MOV CX, MAX_ITEMS       ; EQU constant = 5
  LEA SI, items
  MOV AL, 10
fill:
  MOV [SI], AL
  ADD AL, 10
  INC SI
  LOOP fill

  newline                  ; macro expands inline

  MOV AH, DOS_EXIT        ; EQU constant
  INT 21h
MAIN ENDP
END MAIN

Line-by-line walkthrough

  1. 1. print_str MACRO — defines a reusable template that loads a string address and calls DOS print. Each use is expanded to 3 instructions inline
  2. 2. newline MACRO — prints CR (0Dh) and LF (0Ah) for a new line. Expands to 5 instructions each time used
  3. 3. DOS_PRINT EQU 09h — creates a named constant. Wherever DOS_PRINT appears, the assembler substitutes 09h. No memory used
  4. 4. MAX_ITEMS EQU 5 — another constant. Used for both the DUP count and the loop counter, ensuring consistency
  5. 5. items DB MAX_ITEMS DUP(0) — allocates 5 bytes initialized to zero. DUP tells the assembler to repeat the value
  6. 6. print_str title_msg — the assembler expands this to: LEA DX, title_msg / MOV AH, 09h / INT 21h
  7. 7. MOV CX, MAX_ITEMS — EQU substitution: assembles as MOV CX, 5
  8. 8. The fill loop manually initializes items to [10, 20, 30, 40, 50] by incrementing AL by 10 each iteration
  9. 9. MOV AH, DOS_EXIT — EQU substitution again: assembles as MOV AH, 4Ch

Spot the bug

print_msg MACRO msg
  MOV AH, 09h
  LEA DX, msg
  INT 21h
ENDM

.DATA
  greeting DB 'Hi there', 0Dh, 0Ah, 0

.CODE
  print_msg greeting
  MOV AH, 4Ch
  INT 21h
Need a hint?
Look at the string terminator. What does INT 21h function 09h expect?
Show answer
The string is terminated with 0 (null byte), but DOS function 09h expects a '$' (24h) terminator. The program will print 'Hi there' followed by whatever garbage is in memory until it happens to find a '$'. Fix: change the 0 to '$' in the DB definition.

Explain like I'm 5

Imagine you are building with LEGO. The LEGO bricks are like CPU instructions — they make the actual building. But the instruction booklet tells you 'use 10 red bricks here' (that is DB 10 DUP), 'this section is called the roof' (that is a label), and 'repeat steps 3-5 for each wall' (that is a MACRO). The booklet guides YOU (the assembler), but the final building (machine code) does not contain the booklet — just the bricks.

Fun fact

The MASM MACRO system is actually Turing-complete — you can write conditionals (IF, ELSE, ENDIF), loops (REPT, IRP, IRPC), and string manipulation entirely within the macro language. Some programmers have implemented entire mini-compilers as MASM macro packages that translate a high-level syntax into assembly instructions during assembly time.

Hands-on challenge

Create a macro called print_num that takes a single-digit number (0-9), converts it to its ASCII character, and prints it using INT 21h. Then write a program that uses a loop and your macro to print the digits 0 through 9 on the screen.

More resources

Open interactive version (quiz + challenge) ← Back to course: Microprocessor A–Z