In x86 you don’t need a cascading sequence of jumps, since jmp
can jump over the whole segment. Just a conditional jump like jne
has a limited range. So you can change an errorneous conditional jump to a combination of an unconditional near jump and a conditional short jump:
As an example, change
.MODEL small
.STACK 1000h
.CODE
main:
top:
mov ax, 1
jmp bottom
ORG 1000h ; A big block between top and bottom
bottom:
cmp ax, 0
je top ; **Error** Relative jump out of range by 0F85h bytes
mov ax, 4C00h ; Return 0
int 21h
END main
to
.MODEL small
.STACK 1000h
.CODE
main:
top:
mov ax, 1
jmp bottom
ORG 1000h ; A big block between top and bottom
bottom:
cmp ax, 0
jne skip ; Short conditional jump
jmp top ; Near unconditional jump
skip:
mov ax, 4C00h ; Return 0
int 21h
END main
TASM can do that automagically for you. Place a “JUMPS” at the beginning (or where you need it) of the file:
JUMPS
.MODEL small
.STACK 1000h
.CODE
main:
top:
mov ax, 1
jmp bottom
ORG 1000h ; A big block between top and bottom
bottom:
cmp ax, 0
je top ; TASM will change this line to a JNE-JMP combination
mov ax, 4C00h ; Return 0
int 21h
END main
The 80386 instruction set (ISA) has an instruction for a near conditional jump. If your emulator supports the 80386 ISA (DOSBox does), you can tell TASM to use it. Insert a .386
directive:
.MODEL small
.386 ; Use 80386 instruction set
.STACK 1000h
.CODE
main:
top:
mov ax, 1
jmp bottom
ORG 1000h ; A huge block between top and bottom
bottom:
cmp ax, 0
je top ; Correct jump because of '.386'
mov ax, 4C00h ; Return 0
int 21h
END main
9
solved Jumping back 1000 lines