【问题标题】:Relative jump out of range by相对跳出范围
【发布时间】:2016-09-10 16:06:29
【问题描述】:

每当我输入时,我都会收到消息 "(76)Relative jump out of range by 000Eh bytes"(79)Relative jump out of range by 0007h bytes" CMP 八进制,'3'。我应该一直做到第 7 个八进制数,但是当我尝试做第 3 个八进制数时它总是给我一个错误。我只能做 0,1 和 2,直到它给我一个错误。我不知道我应该做什么。我已经尽我所能尝试了我所教的一切,但我仍然无法得到任何结果。请帮助我。我是新人组装。P.S. 我使用的是 DOSBox 0.74

.Model small

.data
txt1 db "Octal to Binary Converter$"
txt2 db "Enter an Octal Symbol: $"
title0 db "000$"
title1 db "001$"
title2 db "010$"
title3 db "011$"
title4 db "100$"
title5 db "101$"
title6 db "110$"
title7 db "111$"

mess db "Press ESC to exit...$"
invalid db "Input is invalid. Try again.$"
keypress db ?
octal db ?

.code
Start:
Mov AX, @data
Mov ds, ax

sys_st:
Mov AH, 6
Mov AL, 0
Mov BH, 15
Mov ch, 0
Mov cl, 0
Mov DH, 100
Mov DL , 100
Int 10H

Mov AH, 2
Mov BH, 0
Mov DL, 5
Mov DH, 5
Int 10H 

Mov AH, 9
Lea DX, txt1 
Int 21H

JMP sys_st2

sys_st2:
Mov AH, 2
Mov BH, 0
Mov DL, 5
Mov DH, 8
Int 10H 

Mov AH, 9
Lea DX, txt2 
Int 21H 

Mov AH, 1
Int 21H
Mov octal, AL 

CMP octal, '0'
JE sys_0

CMP octal, '1'
JE sys_1

CMP octal, '2'
JE sys_2

CMP octal, '3'
JE sys_3


CMP octal, '0'
JNE sys_invalid

CMP octal, '1'
JNE sys_invalid

CMP octal, '2'
JNE sys_invalid

CMP octal, '3'
JNE sys_invalid

sys_0:
Mov AH, 2
Mov BH, 0
Mov DL, 11
Mov DH, 11 
Int 10H

Mov AH, 9
Lea DX, title0 
Int 21H 

Mov AH, 2 
Mov BH, 0
Mov DL, 5
Mov DH, 15 
Int 10H 

JMP sys_exit

sys_1:
Mov AH, 2 
Mov BH, 0
Mov DL, 11
Mov DH, 11 
Int 10H 

Mov AH, 9
Lea DX, title1
Int 21H 

Mov AH, 2 
Mov BH, 0
Mov DL, 5
Mov DH, 15 
Int 10H 

JMP sys_exit

sys_2:
Mov AH, 2 
Mov BH, 0
Mov DL, 11
Mov DH, 11 
Int 10H 

Mov AH, 9
Lea DX, title2
Int 21H 

Mov AH, 2 
Mov BH, 0
Mov DL, 5
Mov DH, 15 
Int 10H 

JMP sys_exit

sys_3:
Mov AH, 2 
Mov BH, 0
Mov DL, 11
Mov DH, 11 
Int 10H 

Mov AH, 9
Lea DX, title3
Int 21H 

Mov AH, 2 
Mov BH, 0
Mov DL, 5
Mov DH, 15 
Int 10H 

JMP sys_exit

sys_invalid: 
Mov AH, 2 
Mov BH, 0
Mov DL, 5 
Mov DH, 11 
Int 10H 

Mov AH, 9
Lea DX, invalid 
Int 21H 

Mov AH, 1 
Int 21H 
JMP sys_st 

sys_exit: 

Mov AH, 2
Mov BH, 0
Mov DL, 5
Mov DH, 14
Int 10H 

Mov AH, 9
Lea DX, mess 
Int 21H 

Mov AH, 1 
Int 21H 
Mov keypress, AL 

CMP keypress, 27
JNE sys_exit 

JMP exit 

Exit: 
Mov AH, 4ch 
Int 21H 
End Start 

【问题讨论】:

  • 相对跳转只能向前跳转 127 字节或 16 位代码中的 -128。您可以分支到一个标签,然后跳转到您要到达的标签。或者,您必须找到一种方法来重组您的代码,以便相对跳转更接近标签。
  • @MichaelPetch 不正确。较长的相对跳转也可用,但您需要明确请求启用 80386 个操作码。
  • @FUZxxl :虽然没有这样标记,但我从生成的代码中假设他正在生成纯 16 位代码。我很清楚 .386 (和相关的)指令支持 32 位指令。但提供的代码是 16 位 DOS,我假设 OP 可能想要坚持使用 16 位。我不会把水弄混的。
  • @MichaelPetch 这些不是 32 位指令,它们没有 66h 或 67h 前缀。当然,长相对跳转在 16 位模式下工作得很好,只是它们是由 80386 引入的。仅仅因为您的代码在 16 位模式下运行并不意味着您必须将自己限制在 8086 引入的操作码中。

标签: assembly


【解决方案1】:

.386 指令添加到您的文件中,以便能够使用 80386 引入的具有较大偏移量的相对跳转指令。或者,找到有问题的跳转并将其替换为以下内容:

   jnz foo ; this jump is too long

替换为

   jz bar ; opposite conditional
   jmp foo ; unconditional jumps can have larger offsets
bar:
   ...

【讨论】:

  • 这第一部分假设 OP 打算始终以真实硬件或打开了 386 仿真的仿真器为目标(这恰好是 DOSBox 默认情况下所做的)。它不适用于 16 位处理器 286/8086/186 等。这只是您的假设。至于在重复问题中已经得到更好回答的第二部分。
  • @MichaelPetch Dosbox 确实模拟了 80386 个操作码。见here
  • 我在评论中提到了这一点。您可能没有立即看到它,因为我在原版后几秒钟内对其进行了编辑。我还扩展了它以提及真正的硬件。
猜你喜欢
  • 2013-05-21
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2022-12-20
  • 1970-01-01
  • 2010-09-15
相关资源
最近更新 更多