Assembler Directives

SEGMENT, ENDS, ASSUME, DB, DW, EQU.

Darshan N
Updated: 19 March 2026
12 min read

When writing assembly language programs for the 8086 microprocessor, the programmer must not only write instructions for the CPU but also provide structural information to the assembler itself. Assembler directives are pseudo-instructions that guide the assembler during translation of source code into machine code. Unlike executable instructions, directives produce no machine code output but control how the assembler organizes, allocates, and interprets the program.

8086 Assembler Directives OverviewSegment DirectivesSEGMENT ... ENDSASSUME CS:CODE, DS:DATAGROUPData DefinitionDB — Define Byte (8-bit)DW — Define Word (16-bit)DD — Define Doubleword (32-bit)DQ — Define Quadword (64-bit)Symbol and ControlEQU — Equate (constant)PROC ... ENDPPUBLIC / EXTERNEND — End of programDirectives guide the assembler; they do not generate machine code.
Figure 1: Categories of assembler directives used in 8086 assembly programming

Core Concept Explanation

An assembler translates human-readable mnemonics into binary machine code. However, the assembler also needs to know how to organize memory, what names refer to constants, and where the program ends. Directives fulfill this need. They are instructions to the assembler program itself, not to the 8086 CPU. The CPU never executes a directive.

The SEGMENT directive marks the beginning of a logical memory segment and is always paired with an ENDS directive that marks the end of that segment. This tells the assembler to group the enclosed code or data into one logical unit. A typical 8086 program has at least a code segment, a data segment, and optionally a stack segment.

The ASSUME directive tells the assembler which segment register is associated with which segment name. Without ASSUME, the assembler cannot resolve segment references correctly. For example, ASSUME CS:CODE, DS:DATA tells the assembler that CS points to the CODE segment and DS points to the DATA segment.

The DB (Define Byte) directive allocates one or more bytes of memory in the data segment and optionally initializes them with values. Similarly, DW (Define Word) allocates 16-bit (2-byte) words. These directives are the primary means of declaring variables in 8086 assembly.

The EQU directive defines a symbolic constant. Unlike DB or DW, EQU does not allocate any memory. It simply assigns a numeric value to a label so the programmer can use a meaningful name instead of a raw number throughout the program. This improves readability and maintainability.

Detailed Directive Reference

SEGMENT and ENDS

Every segment in an 8086 assembly program must be declared using SEGMENT and closed with ENDS. The assembler uses these boundaries to compute the starting offset of each instruction and data item within the segment. The linker later assigns physical addresses to each segment.

A minimal segment declaration looks like: DATA SEGMENT followed by variable declarations, then DATA ENDS. The name before SEGMENT becomes the segment identifier used in the ASSUME directive. The 8086 can address up to 64 KB per segment, and a program can have multiple named segments.

DB and DW

DB allocates bytes. A single byte value, a list of bytes, or an ASCII string can all be defined using DB. For example, MSG DB 'HELLO' allocates five consecutive bytes and stores the ASCII codes of H, E, L, L, O. DW allocates 16-bit words and stores them in little-endian format, meaning the low byte is stored first.

Using a question mark as initializer, such as VAR DB ?, allocates the byte but leaves its value uninitialized (assembler sets it to zero by default in many assemblers). The DUP operator works with DB and DW to allocate repeated values. For example, BUFFER DB 100 DUP(0) allocates 100 bytes all initialized to zero.

EQU

EQU is a textual substitution directive. When the assembler encounters MAX EQU 100 and later sees the label MAX in the code, it replaces MAX with 100 before assembling. EQU does not consume memory space. It is also used to equate register aliases or complex expressions. EQU is evaluated at assembly time, making it a true compile-time constant.

Mathematical Expression

While assembler directives themselves are not mathematical, they are used to compute memory offsets. The physical address in 8086 is computed as:

Physical Address = Segment Register x 10H + Offset Address

When the assembler processes SEGMENT and data directives, it computes the offset of each variable from the start of its segment. The linker assigns the segment base at link time. If DS = 2000H and the offset of variable VAR is 0005H, then the physical address of VAR is 2000H x 10H + 0005H = 20005H.

Practical Understanding

In a real 8086 program, all directives work together to produce a properly structured executable. The data segment holds all variables declared using DB and DW. The code segment contains all executable instructions and procedure definitions. The ASSUME directive ensures the assembler generates correct segment override prefixes where needed.

Without assembler directives, an 8086 assembly source file would be an unstructured stream of instructions with no way to organize data, define constants, or indicate the end of the program. Directives are what make structured, modular assembly programming possible.

Solved Example

Consider a program that defines two bytes A = 05H and B = 03H in the data segment, with MAX defined as a constant 10H using EQU. The physical address of the second variable B needs to be computed given DS = 3000H.

Example
Given:
DS = 3000H
Variable A defined first using DB → offset 0000H
Variable B defined second using DB → offset 0001H

Why this formula applies:
In 8086, physical address = (Segment Register x 16) + Offset
Multiplying by 16 is equivalent to shifting left by 4 bits (one hex digit)

Formula:
Physical Address = DS x 10H + Offset

Substitution:
Physical Address of B = 3000H x 10H + 0001H
= 30000H + 0001H

Calculation:
= 30001H

Final Answer: Physical Address of variable B = 30001H
Exam Tip: GATE frequently asks whether EQU allocates memory. It does NOT. EQU is a compile-time substitution only. Also remember that DB stores data in byte units while DW stores in word (2-byte) units with little-endian byte ordering.

Mechanism Diagram

Assembly Source to Object Code: Role of DirectivesSource FileDATA SEGMENTMSG DB 'HI'MAX EQU 100DATA ENDSCODE SEGMENTASSUME CS:CODEMOV AX, DATACODE ENDSENDAssemblerProcesses DirectivesSegment layout computedEQU substitutedOffsets calculatedNo code for directivesObject FileDATA Segment:48H 49H (HI bytes)CODE Segment:B8H xxH (MOV AX)EQU: No bytesgenerated in outputDirectives resolveto zero bytesDirective (no code)Executable Instruction
Figure 2: How assembler directives control segment layout and symbol resolution without generating machine code

Key Points on Directive Behavior

  • SEGMENT and ENDS define logical memory sections; every segment must be explicitly closed with ENDS before another begins.
  • ASSUME does not physically load any segment register; it only informs the assembler of the association so it can compute addresses correctly.
  • DB allocates 1 byte per value, while DW allocates 2 bytes per value in little-endian order.
  • EQU performs text substitution at assembly time and generates absolutely zero bytes in the output object file.
  • The END directive marks the logical end of the source file; anything written after END is ignored by the assembler.
  • DUP operator multiplies allocation: 50 DUP(0) with DB allocates 50 zero-initialized bytes.

Quick Revision

  • Assembler directives are instructions to the assembler, not to the CPU. They generate no machine code output.
  • SEGMENT ... ENDS: defines start and end of a logical segment (CODE, DATA, STACK).
  • ASSUME CS:SEG, DS:SEG: tells assembler which segment register maps to which segment name.
  • DB allocates bytes; DW allocates 16-bit words in little-endian format. DUP operator enables block allocation.
  • EQU assigns a compile-time constant to a label — no memory is allocated, no machine code generated.
  • Physical address formula: PA = Segment Register x 10H + Offset. Applies when computing where DB/DW variables reside.
  • Common trap: ASSUME does not set DS or CS registers at runtime. You must explicitly load DS with MOV AX, DATA and MOV DS, AX in your code.

Assembly Language Directives

Identify non-executable instructions for the assembler.

Question 1 of 3

Q1.What is the function of the ASSUME directive in an 8086 assembly language program?