Relationship Between Modular Program Structure and Segments
In the 8086/8088 architecture, memory is managed in segments. Therefore, when a complex program consists of multiple modules, each module may contain several segments. The linker needs to combine these scattered segments into a final executable program.
Basic Concepts of Module Linking:
- Source Module: Can be written in assembly language or high-level language
- Object Module (OBJ): Generated by the assembler or compiler
- Executable Program: Formed by the linker combining multiple OBJ files
Complete Segment Definition Method
The complete segment definition provides full control over segment attributes, suitable for scenarios requiring precise memory management.
Complete Segment Definition Syntax:
SegmentName SEGMENT [Align Type] [Combine Type] [Class]
; Segment content
SegmentName ENDS
Explanation of Segment Definition Parameters:
-
Align Type:
<span>BYTE</span>: Segment can start from any byte<span>WORD</span>: Segment starts at word boundary (even address)<span>DWORD</span>: Segment starts at double word boundary (address is a multiple of 4)<span>PARA</span>(default): Segment starts at paragraph boundary (address is a multiple of 16)<span>PAGE</span>: Segment starts at page boundary (address is a multiple of 256)
Combine Type:
<span>PRIVATE</span>(default): Segment is independent and not combined with other segments<span>PUBLIC</span>: Segments with the same name are linked into one segment<span>STACK</span>: Same as PUBLIC but specifically for stack segments<span>COMMON</span>: Segments with the same name overlap, length is that of the longest segment<span>MEMORY</span>: Similar to PUBLIC but placed at the highest address<span>AT Expression</span>: Segment is located at the boundary specified by the expression
Class:
- A string enclosed in single quotes, the linker will store segments of the same class consecutively
Example of Multi-Module Program
Example 1: Segment Combination of Multiple Modules
; Module 1 MODULE1.ASM
DATA1 SEGMENT PUBLIC 'DATA'
MESSAGE1 DB 'Hello from Module1', 0DH, 0AH, '$'
DATA1 ENDS
CODE1 SEGMENT PUBLIC 'CODE'
ASSUME CS:CODE1, DS:DATA1
PUBLIC DISPLAY_MESSAGE1
DISPLAY_MESSAGE1 PROC FAR
MOV AH, 09H
LEA DX, MESSAGE1
INT 21H
RET
DISPLAY_MESSAGE1 ENDP
CODE1 ENDS
END
; Module 2 MODULE2.ASM
DATA1 SEGMENT PUBLIC 'DATA'
MESSAGE2 DB 'Hello from Module2', 0DH, 0AH, '$'
DATA1 ENDS
CODE1 SEGMENT PUBLIC 'CODE'
ASSUME CS:CODE1, DS:DATA1
PUBLIC DISPLAY_MESSAGE2
DISPLAY_MESSAGE2 PROC FAR
MOV AH, 09H
LEA DX, MESSAGE2
INT 21H
RET
DISPLAY_MESSAGE2 ENDP
CODE1 ENDS
END
; Main Module MAIN.ASM
EXTRN DISPLAY_MESSAGE1:FAR, DISPLAY_MESSAGE2:FAR
STACK SEGMENT PARA STACK 'STACK'
DB 100 DUP(?)
STACK ENDS
DATA1 SEGMENT PUBLIC 'DATA'
MAIN_MSG DB 'Main program starts', 0DH, 0AH, '$'
DATA1 ENDS
CODE1 SEGMENT PUBLIC 'CODE'
ASSUME CS:CODE1, DS:DATA1, SS:STACK
START:
MOV AX, DATA1
MOV DS, AX
; Display main module message
MOV AH, 09H
LEA DX, MAIN_MSG
INT 21H
; Call procedure from Module 1
CALL DISPLAY_MESSAGE1
; Call procedure from Module 2
CALL DISPLAY_MESSAGE2
MOV AH, 4CH
INT 21H
CODE1 ENDS
END START
Analysis of the Linking Process
- DATA1 Segment: Due to the use of
<span>PUBLIC</span>combine type, the DATA1 segments from the three modules will be linked into one physical segment - CODE1 Segment: Similarly, using
<span>PUBLIC</span>combine type, the code segments from the three modules will be linked - STACK Segment: Defined as
<span>STACK</span>type in the main module, will be recognized as the program stack segment
Advanced Usage of Segment Definitions
Example 2: Segments with Different Combine Types
; Module A MODULEA.ASM
SHARED_DATA SEGMENT COMMON 'DATA'
BUFFER DB 100 DUP(?)
SHARED_DATA ENDS
UNIQUE_DATA SEGMENT PRIVATE 'DATA'
LOCAL_MSG DB 'ModuleA local data', 0DH, 0AH, '$'
UNIQUE_DATA ENDS
CODE_A SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE_A, DS:UNIQUE_DATA, ES:SHARED_DATA
PUBLIC INIT_BUFFER
INIT_BUFFER PROC FAR
MOV AX, SHARED_DATA
MOV ES, AX
MOV CX, 100
MOV AL, 0
LEA DI, BUFFER
REP STOSB
RET
INIT_BUFFER ENDP
CODE_A ENDS
END
; Module B MODULEB.ASM
SHARED_DATA SEGMENT COMMON 'DATA'
BUFFER DB 100 DUP(?)
SHARED_DATA ENDS
CODE_B SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE_B, ES:SHARED_DATA
PUBLIC USE_BUFFER
USE_BUFFER PROC FAR
MOV AX, SHARED_DATA
MOV ES, AX
; Use shared buffer
RET
USE_BUFFER ENDP
CODE_B ENDS
END
; Main Module MAIN.ASM
EXTRN INIT_BUFFER:FAR, USE_BUFFER:FAR
STACK SEGMENT PARA STACK 'STACK'
DB 200 DUP(?)
STACK ENDS
CODE_MAIN SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE_MAIN, SS:STACK
START:
; Initialize shared buffer
CALL INIT_BUFFER
; Use shared buffer
CALL USE_BUFFER
MOV AH, 4CH
INT 21H
CODE_MAIN ENDS
END START
Key Points Explanation:
- COMMON Combine Type: The SHARED_DATA segment in both modules will overlap, sharing the same memory area
- PRIVATE Combine Type: The UNIQUE_DATA segment in ModuleA remains independent
- Memory Mapping:
- After linking, there will be only one instance of the SHARED_DATA segment
- The code segments from both modules (CODE_A and CODE_B) will be linked into one segment
- The CODE_MAIN from the main module will also be linked with the previous two code segments
Segment Positioning and Linking Rules
-
Combination of Segments with the Same Name and Class:
- If the combine type is PUBLIC, the linker connects these segments in order
- If COMMON, these segments overlap
- If STACK, all STACK segments are combined to form a stack segment
Segment Order Control:
- The linker defaults to arrange segments in the order provided by the object modules
- Segment order can be controlled using class names, with segments of the same class stored consecutively
Segment Address Allocation:
- The linker determines the starting address of segments based on the align type
- Final memory layout is calculated considering the lengths of each segment and their combine types
Practical Development Recommendations
-
Naming Conventions:
- Use consistent naming and classes for public segments
- Avoid segment name conflicts across different modules
Combine Type Selection:
- Code segments typically use PUBLIC combine
- Data segments should choose between PUBLIC or COMMON based on needs
- Stack segments must use STACK combine
Align Type Selection:
- Code segments usually use PARA or PAGE
- Data segments can use PARA or WORD
- Performance-critical code may consider DWORD alignment
Debugging Tips:
- Use MAP files to check the final segment layout
- Pay attention to segment register initialization
- Ensure ASSUME statements correctly reflect actual segment relationships
By properly utilizing segment definition attributes, precise control over program memory layout can be achieved, enabling efficient modular program design.