Assembly 跳回1000行

Assembly 跳回1000行,assembly,x86,dos,x86-16,tasm,Assembly,X86,Dos,X86 16,Tasm,我试着做一个代码,当你在最后的时候,它会问你是否想再试一次。如果你按“y”,那么它将跳回1000行,就在程序的开头 很明显,它不起作用,因为我得到了错误“跳跃相对超出范围”。所以我每50行跳一次,总共跳了20次,就像 start: . s20: jmp start . . . s2: jmp s3 . s1: jmp s2 . jmp s1 现在在做了这些之后,我运行了程序,当我按下“y”键时,TASM有点僵住了。它只是显示最后一个屏幕,带有“y”输入和闪烁。我再也不能按字符了。在x86中,您

我试着做一个代码,当你在最后的时候,它会问你是否想再试一次。如果你按“y”,那么它将跳回1000行,就在程序的开头

很明显,它不起作用,因为我得到了错误“跳跃相对超出范围”。所以我每50行跳一次,总共跳了20次,就像

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

现在在做了这些之后,我运行了程序,当我按下“y”键时,TASM有点僵住了。它只是显示最后一个屏幕,带有“y”输入和闪烁。我再也不能按字符了。

在x86中,您不需要级联跳转序列,因为
jmp
可以跳过整个段。像
jne
这样的条件跳转的范围是有限的。因此,您可以将错误条件跳转更改为无条件近跳转和条件短跳转的组合:

例如,改变

.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

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)有一条用于近条件跳转的指令。如果您的模拟器支持80386ISA(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

正如你所描述的,它应该是有效的。错误一定在别处,你是说“TASM 4.1”而不是“TASM 1.4”?有点僵住了?你是不是忘了跳过把无条件的跳跃放在鲑鱼梯上跳过向后的跳跃?您的代码可能处于
start:
s20:jmp start
之间的无限循环中。您好,谢谢。不,我确实做了无条件跳跃。不管怎样,我删除了salmon梯形图,只在末尾留下了一个jmp开始,程序现在正在运行:)@xTan:您正在使用(来自sourceforge)吗?如果so ii在DOSBox(也安装了)内部有效地安装了TASM 3.0/TD 3.1,噢,snap!!!所以一个无条件跳转(jmp)实际上没有像条件跳转那样的范围限制?该死,我在这里,跳了50下!!不管怎样,谢谢兄弟。你是个救生员D哦,是的,我的程序正在运行:)这只是TASM的限制吗?74 cb是
je rel8
(短跳转)的操作码,但0F 84 cd是一个近跳转:
je rel32
je rel16
(取决于前缀和当前模式)。英特尔手册介绍了在实际模式下跳转到当前代码段之外时的异常情况(例如,如果使用32位地址大小前缀),因此,这些近跳转编码不限于32位/64位模式。只要你实际上不需要跳远来改变片段,你就不需要
jcc/jmp
对,对吧?@PeterCordes:这是8086限制。80386架构引入了近似条件跳转
0F 8x…
。@rkhb:好的,OP没有说他针对的是那么旧的硬件。。。这对于这些16位DOS或者其他问题来说是正常的吗?假设每个人都知道这段代码将在什么样的环境中运行?这就像有些人认为x86 asm自动意味着不编写(内部循环)在Unix或Windows等普通操作系统中进行正常系统调用的普通64位程序一样。@MichaelPetch:谢谢。我不知道TASM“1.4”的存在。被称为TASM-5的TASM自称为“涡轮汇编程序版本4.1版权所有(c)1988年,1996年Borland International”。
.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