如何修复:相关跳转超出范围 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.
如何修复:此代码中的“相关跳转超出范围 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.