问题
I was trying to make a code, that when you're at the very end, it will ask you if you want to try again. If you press 'y', then it will jump back a 1000 lines, right at the beginning of the program.
Well obviously, it didn't work out, as I got the error "jump relative out of range". So I made jumps every 50 lines, having a total of 20 jumps, like
start:
.
s20: jmp start
.
.
.
s2: jmp s3
.
s1: jmp s2
.
jmp s1
Now after doing that, I ran the program, and when I pressed 'y', TASM kind of froze. It was just displaying the last screen, with the 'y' input, and a blinking _. I couldn't press a character anymore.
回答1:
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
来源:https://stackoverflow.com/questions/32623899/jumping-back-1000-lines