2015-09-17 6 views
-2

Я пытался сделать код, который, когда вы в самом конце, попросит вас, хотите ли вы попробовать еще раз. Если вы нажмете «y», тогда он вернется на 1000 строк, прямо в начале программы.Прыжки назад 1000 строк

Ну, очевидно, это не сработало, так как я получил ошибку «прыгать относительно вне диапазона». Так что я сделал подскакивает каждые 50 строк, имеющих в общей сложности 20 прыжков, как

start: 
. 
s20: jmp start 
. 
. 
. 
s2: jmp s3 
. 
s1: jmp s2 
. 
jmp s1 

Теперь после того, как сделать это, я запустил программу, и когда я нажал «у», TASM вид замерзала. Он просто показывал последний экран с входом «y» и миганием _. Я больше не мог нажимать персонажа.

Спасибо.

+0

Как вы описали, оно должно работать. Ошибка должна быть в другом месте. Вы имели в виду «TASM 4.1» вместо «TASM 1.4»? – rkhb

+0

Вид замерзания? Вы забыли пропустить безусловные прыжки, чтобы пропустить прыжки назад в лососевую лестницу? Вероятно, ваш код находится в бесконечном цикле между 'start:' и 's20: jmp start'. –

+0

привет, спасибо. нет, я сделал безусловные прыжки. в любом случае, я удалил лосось-лестницу и просто оставил jmp-старт прямо в конце, и программа теперь работает :) – xTan

ответ

5

В x86 вам не нужна каскадная последовательность прыжков, так как jmp может перепрыгнуть через весь сегмент. Просто условный прыжок, такой как jne, имеет ограниченный диапазон. Таким образом, вы можете изменить errorneous условный переход к комбинации безусловного близкого перехода и условного короткого прыжка:

В качестве примера, изменение

.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 

в

.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 может сделать автоматически для вас. Разместить запрос «ПЕРЕХОД» в начале (или там, где вам это нужно) файл:

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 

Набор 80386 инструкции (ISA) имеет инструкцию для почти условного перехода. Если ваш эмулятор поддерживает ISA 80386 (DOSBox делает), вы можете сказать TASM использовать его. Вставьте директиву .386:

.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 
+0

oh snap !!! поэтому безусловный переход (jmp) на самом деле не имеет ограничений по диапазону, таких как условные переходы? черт, и вот я был, делая что-то вроде 50 прыжков !! * facepalm * хорошо в любом случае, спасибо брату. вы спасатель жизни! : D ... о, да, и моя программа работает сейчас :) – xTan

+0

Это просто ограничение TASM? 74 * cb * - это код операции для 'je rel8' (короткий прыжок), но 0F 84 * cd * - это ближайший скачок:' JE rel32' или 'JE rel16' (в зависимости от префиксов и текущего режима.) Руководство Intel говорит что-то об исключениях в реальном режиме, если вы прыгнете за пределы текущего сегмента кода (например, если используется 32-битный префикс размера адреса), поэтому эти кодировки с близким скачком не ограничены 32-битным/64-битным режимом. До тех пор, пока вам действительно не нужен перескок для изменения сегментов, вам не нужна пара 'jcc/jmp', правильно? –

+1

@PeterCordes: Это ограничение 8086. Ближайший условный переход «0F 8x ...» был введен с архитектурой 80386. – rkhb