Principle of Limitations on Jump Instructions
In 8086 assembly language, displacement-based jump instructions (such as <span>jmp short</span>, <span>jmp near ptr</span>, <span>jcxz</span>, <span>loop</span>, etc.) share a common characteristic: their jump range is limited by the displacement value. This limitation arises because the machine code for these instructions contains only a one-byte or two-byte displacement, rather than a complete address.
Range of Displacement Representation
-
Short Jump Instructions (such as
<span>jmp short</span>,<span>jcxz</span>,<span>loop</span>):
- Uses an 8-bit signed displacement
- Range: -128 to +127 bytes
- Machine code format: opcode + 1-byte displacement
Near Jump Instructions (such as <span>jmp near ptr</span>):
- Uses a 16-bit signed displacement
- Range: -32768 to +32767 bytes
- Machine code format: opcode + 2-byte displacement
Error Examples of Out-of-Range Jumps
Example 1: Short Jump Out of Range
; Example 1: Short jump out of range error
assume cs:code
code segment
start:
jmp short s ; Error: Jump out of range
db 128 dup(0) ; 128 bytes of data
s:
mov ax, 0ffffh
mov ax, 4C00h
int 21h
code ends
end start
Error Analysis:
<span>jmp short s</span>is a short jump, with a maximum jump range of 127 bytes- However, there are 128 bytes of data between the jump instruction and the target label
- Thus, the displacement exceeds the representable range of an 8-bit signed number (-128 to 127)
- The assembler will report an error: “Jump out of range by X bytes”
Example 2: Near Jump Out of Range
; Example 2: Near jump out of range error
assume cs:code
code segment
start:
jmp near ptr s ; Error: Jump out of range
; A large amount of code or data, exceeding 32767 bytes
; Here, using a pseudo-instruction to simulate a large amount of data
db 32768 dup(0) ; 32768 bytes of data
s:
mov ax, 0ffffh
mov ax, 4C00h
int 21h
code ends
end start
Error Analysis:
<span>jmp near ptr s</span>is a near jump, with a maximum jump range of 32767 bytes- However, there are 32768 bytes of data between the jump instruction and the target label
- Thus, the displacement exceeds the representable range of a 16-bit signed number (-32768 to 32767)
- The assembler will report an error: “Jump out of range by X bytes”
Solutions
Solution 1: Use Absolute Address Jump
; Solution 1: Use absolute address jump
assume cs:code
code segment
start:
jmp far ptr s ; Use far jump, absolute address
db 128 dup(0) ; 128 bytes of data
s:
mov ax, 0ffffh
mov ax, 4C00h
int 21h
code ends
end start
Explanation:
<span>jmp far ptr s</span>is an inter-segment jump, using an absolute address instead of a relative displacement- It is not limited by distance and can jump to any address
- However, the instruction length is longer (5 bytes), and execution speed is slightly slower
Solution 2: Use Intermediate Jump
; Solution 2: Use intermediate jump
assume cs:code
code segment
start:
jmp intermediate ; First jump to an intermediate point
db 128 dup(0) ; 128 bytes of data
intermediate:
jmp s ; Then jump to the target
; More code...
s:
mov ax, 0ffffh
mov ax, 4C00h
int 21h
code ends
end start
Explanation:
- Using two-level jumps to solve the out-of-range problem
- Each jump is within the valid range
- Increases one instruction but maintains code flexibility
Solution 3: Reorganize Code Structure
; Solution 3: Reorganize code structure
assume cs:code
code segment
start:
; Move the code to be skipped to the end
jmp s ; Directly jump to the target
; Main program code
main_code:
; This is the code that was originally before the jump
mov ax, 4C00h
int 21h
; Data area
s:
db 128 dup(0) ; 128 bytes of data
; More code...
code ends
end start
Explanation:
- By reorganizing the code structure, long-distance jumps are avoided
- Moves the data area to after the code
- May require adjustments to program logic
Special Considerations
Limitations of Debug Format Instructions
; Error example: Using Debug format instructions
assume cs:code
code segment
start:
jmp 2000:0100 ; Error: Compiler does not recognize this format
; The correct way is to use far jump
; jmp far ptr [label] or directly specify the address
code ends
end start
Explanation:
<span>jmp 2000:0100</span>is a format used in Debug- The assembly compiler does not recognize this format and will report an error
- In the source program, standard assembly syntax should be used
Correct Use of Far Jump
; Correct use of far jump
assume cs:code
code segment
start:
; Method 1: Use label
jmp far ptr target
; Method 2: Directly specify the address (needs to know the exact address)
; db 0EAh ; Far jump opcode
; dw offset target ; Offset address
; dw seg target ; Segment address
db 128 dup(0) ; Large amount of data
target:
mov ax, 0ffffh
mov ax, 4C00h
int 21h
code ends
end start
Practical Programming Advice
-
Estimate Jump Distance: When writing code, estimate the distance between the jump instruction and the target, and choose the appropriate jump type.
-
Use Modular Design: Organize code into small functional modules to reduce the need for long-distance jumps.
-
Utilize Assembler Error Messages: When encountering a “Jump out of range” error, carefully check the number of out-of-range bytes in the error message, then adjust the code.
-
Consider Performance Impact: Short jumps and near jumps are more efficient than far jumps and should be prioritized unless the distance exceeds the range.
-
Code Relocation Considerations: If the code needs to be relocated, avoid using absolute address jumps and try to use relative displacement jumps.
Conclusion
Displacement-based jump instructions are very common in 8086 assembly language, but they are all limited by the range of displacement representation. When the jump distance exceeds this range, the assembler will report an error. Solutions to this problem include using far jumps, intermediate jumps, or reorganizing the code structure.
Understanding these limitations and mastering the corresponding solutions is crucial for writing correct and efficient assembly programs. Additionally, care should be taken to avoid using Debug-specific instruction formats and instead use standard assembly syntax.