如何修复:相关跳转超出范围 0007h 字节

How to Fix: Related jump out of range by 0007h bytes

如何修复:此代码中的“相关跳转超出范围 0007h 字节”?使用notepad++在DOSBox中执行

我刚接触跳转语法,不知道为什么会出错。这个程序还没有完成,我只是想看看跳转是否出错了,这样我就可以继续进行另一个流程了。

记事本+代码:

.model small
.stack 100h
.data                                                       ;string

        Menu    db 0dh,0ah, "   MAIN MENU   $"              ;MAIN MENU
        Cal     db 0dh,0ah,0dh,0ah, "[1]Calculator $"
        Con     db 0dh,0ah, "[2]Conversion $"
        Ex      db 0dh,0ah, "[3]Exit $"
        
        Pik     db 0dh,0ah,0dh,0ah, "Pick your choice: $"   ;Choose
        
        SubC    db 0dh,0ah, "Calculator Sub-MENU $"         ;Calculator Sub-MENU
        Ad      db 0dh,0ah,0dh,0ah,"[1]Addition $"
        Su      db 0dh,0ah, "[2]Subtraction $"
        Mu      db 0dh,0ah, "[3]Multiplication $"
        Dv      db 0dh,0ah, "[4]Division $"
        BkCM    db 0dh,0ah, "[5]Back to Main MENU $"
        
        PikA    db 0dh,0ah, "Calculator: Addition $"        ;Calculator: Addition
        PikS    db 0dh,0ah, "Calculator: Subtraction $"     ;Calculator: Subtraction
        PikM    db 0dh,0ah, "Calculator: Multiplication $"  ;Calculator: Multiplication
        PikD    db 0dh,0ah, "Calculator: Division $"        ;Calculator: Division
        
        BsT     db 0dh,0ah,0dh,0ah,"[1]Base 10 $"           ;Calculator: Base
        BsE     db 0dh,0ah,"[2]Base 11 $"
        BkS     db 0dh,0ah,"[3]Back to Sub-MENU $"          ;ack to Sub-MENU
        
        SubV    db 0dh,0ah, "Conversion Sub-MENU $"         ;Conversion Sub-MENU
        Hex     db 0dh,0ah,0dh,0ah,"[1]Base 8 to Base 16 $"
        Oct     db 0dh,0ah, "[2]Base 16 to Base 8 $"
        Deci    db 0dh,0ah, "[3]Base 8 to Base 10 $"
        BkVM    db 0dh,0ah, "[4]Back to Main MENU $"

        Spc     db 0dh,0ah, " $ "                           ;Spacing
.code
main proc
        
        mov ax,@data                    ;initialize ds
        mov ds,ax
            
        Start:                          ;show MAIN MENU
            mov ah,09h
            lea dx, Spc                 ;new Line
            int 21h
            
            lea dx, Menu                ;Main Menu
            int 21h
            lea dx, Cal
            int 21h
            lea dx, Con
            int 21h
            lea dx, Ex
            int 21h
        
            lea dx, Pik                 ;Choise
            int 21h
            mov ah,01h
            int 21h
        
            cmp al,31h                  ;cmp Logic
            je CalSub
            cmp al,32h
            je ConSub
            cmp al,33h
            jge ExitP
        
        CalSub:                         ;show Calculator Sub-MENU
            mov ah,09h
            lea dx, Spc                 ;new Line
            int 21h
            
            lea dx, SubC                ;Calculator Sub-MENU
            int 21h
            lea dx, Ad
            int 21h
            lea dx, Su
            int 21h
            lea dx, Mu
            int 21h
            lea dx, Dv
            int 21h
            lea dx, BkCM
            int 21h
            
            lea dx,Pik                  ;Choice
            int 21h
            mov ah,01h
            int 21h
            
            cmp al,31h                  ;cmp Logic
            je CalAd
            cmp al,32h
            je CalSu
            cmp al,33h
            je CalMu
            cmp al,34h
            je CalDv
            cmp al,35h
            je Start
            
        ConSub:                         ;show Conversion Sub-MENU
            mov ah,09h                  
            lea dx, Spc                 ;new Line
            int 21h
            
            lea dx, SubV                ;Conversion Sub-MENU
            int 21h
            lea dx, Hex
            int 21h
            lea dx, Oct
            int 21h
            lea dx, Deci
            int 21h
            lea dx, BkVM
            int 21h
            
            lea dx, Pik                 ;Choice
            int 21h

        ExitP:
            int 20                      ;Stop Program
        
        CalAd:                          ;show Addition
            mov ah,09               
            lea dx,Spc                  ;new Line
            int 21h
            
            lea dx,PikA                 ;Addition
            int 21h
            
            cmp al,31h                  ;Base Choices
            je Base
            
        CalSu:                          ;show Subtraction
            mov ah,09
            lea dx,Spc                  ;new Line
            int 21h
            
            lea dx,PikS                 ;Subtraction
            int 21h
            
            cmp al,32h                  ;Base Choices
            je Base
        
        CalMu:                          ;show Multiplication
            mov ah,09
            lea dx,Spc                  ;new Line
            int 21h
            
            lea dx,PikM                 ;Multiplication
            int 21h
            
            cmp al,33h                  ;Base Choices
            je Base
            
        CalDv:                          ;show Division
            mov ah,09
            lea dx,Spc                  ;new Line
            int 21h
            
            lea dx,PikD                 ;Division
            int 21h
            
            cmp al,34h                  ;Base Choices
            je Base
            
        Base:                           ;Show Base
            mov ah,09h                  ;Base
            lea dx,BsT
            int 21h
            lea dx,BsE
            int 21h
            lea dx,BkS
            int 21h
            
            lea dx,Pik                  ;Choice
            int 21h
            mov ah,01h
            int 21h
            
            cmp al,33h                  ;cmp to back in Calculator Sub-MENU
            jnz CalSub
            
        mov ah,4Ch                      ;end here
        int 21h

main endp
end main

弹出的错误:

短跳转 x86 指令的范围限制为-128..+127。如果目标距离较远,则必须对其进行不同的编码,使用带有反转条件代码的短条件跳转绕过近跳转。将目标子过程移近 cmp logic,或替换

        cmp al,31h                  ;cmp Logic
        je CalSub
        cmp al,32h
        je ConSub

        cmp al,31h ; cmp Logic
        jne @@not1 ; Inverted condition.                  
        jmp CalSub ; Proxy near jump without range restriction.
@@not1: cmp al,32h
        jne @@not2 ; Inverted condition.                  
        jmp ConSub ; Proxy near jump without range restriction.
@@not2:

有些汇编程序会自动为 CPU 早于 386 的 没有条件 near jump

另一种解决方案是 跳跃 table 具有目标偏移量的单词:

.data
JumpTable: DW CalSub, ConSub, ExitP
.code            ; cmp Logic 
      sub al,31h ; Let AL=0,1,2 for CalSub, ConSub, ExitP.
      xor bx,bx
      mov bl,al  ; MOVZX BX,AL would be better, but N/A on 086.
      add bx,bx  ; Let BX=0,2,4 for CalSub, ConSub, ExitP.
      jmp [JumpTable+BX] ; Use BX as an index to JumpTable.