-3

I was trying to make a code, that when you're at the very end, it will ask you if you want to try again. If you press 'y', then it will jump back a 1000 lines, right at the beginning of the program.

Well obviously, it didn't work out, as I got the error "jump relative out of range". So I made jumps every 50 lines, having a total of 20 jumps, like

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

Now after doing that, I ran the program, and when I pressed 'y', TASM kind of froze. It was just displaying the last screen, with the 'y' input, and a blinking _. I couldn't press a character anymore.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
xTan
  • 77
  • 1
  • 11
  • As you described it, it should work. The error must be elsewhere, Did you mean "TASM 4.1" instead of "TASM 1.4"? – rkhb Sep 17 '15 at 09:29
  • Kind of froze? Did you forget to skip put unconditional jumps to skip over the backward-jumps in the salmon-ladder? Your code is probably in an infinite loop between `start:` and `s20: jmp start`. – Peter Cordes Sep 17 '15 at 15:28
  • hi, thanks. no I did put unconditional jumps. anyways, I removed the salmon-ladder and just left a jmp start right at the end and the program is working now :) – xTan Sep 17 '15 at 15:53
  • @xTan : Are you using [Tasm Installer 1.4](http://sourceforge.net/projects/tasmforwindows/) (from sourceforge)? If so ii is effectively TASM 3.0/TD 3.1 inside of DOSBox (which also gets installed) – Michael Petch Sep 17 '15 at 18:53

1 Answers1

6

In x86 you don't need a cascading sequence of jumps, since jmp can jump over the whole segment. Just a conditional jump like jne has a limited range. So you can change an errorneous conditional jump to a combination of an unconditional near jump and a conditional short jump:

As an example, change

.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

to

.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 can do that automagically for you. Place a "JUMPS" at the beginning (or where you need it) of the file:

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

The 80386 instruction set (ISA) has an instruction for a near conditional jump. If your emulator supports the 80386 ISA (DOSBox does), you can tell TASM to use it. Insert a .386 directive:

.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
rkhb
  • 14,159
  • 7
  • 32
  • 60
  • oh snap!!! so an unconditional jump (jmp) doesn't really have a range limitation like conditional jumps? damn, and here I was, doing something like 50 jumps!! *facepalm* well anyways, thanks bro. you're a life saver! :D... oh yeah, and my program is working now :) – xTan Sep 17 '15 at 14:38
  • Is this just a TASM limitation? 74 *cb* is the opcode for `je rel8` (short jump), but 0F 84 *cd* is a near jump: `JE rel32` or `JE rel16` (depending on prefixes and current mode.) Intel's manual says something about exceptions in Real mode if jumping outside the current code segment (e.g. if 32bit address-size prefix is used), so these near-jump encodings aren't limited to 32bit / 64bit mode. As long as you don't actually need a far-jump to change segments, you don't need a `jcc / jmp` pair, right? – Peter Cordes Sep 17 '15 at 15:23
  • 2
    @PeterCordes: It's an 8086 limitation. The near conditional jump `0F 8x ...` was introduced with the 80386 architecture. – rkhb Sep 17 '15 at 15:50
  • @rkhb: ok, the OP didn't say he was targetting hardware that old... Is that normal for these 16 bit DOS or whatever this is questions that just assume everyone knows what kind of environment this code is going to run in? It's like some people think x86 asm automatically implies not writing (inner loops in) normal 64bit programs that make normal system calls in normal OSes like Unix or Windows. – Peter Cordes Sep 17 '15 at 16:22
  • @PeterCordes: TASM is usually used today in a DOS environment to produce DOS programs, i.e. 16-bit 8086. There are extended options in TASM, but I don't know what DOS-emulatur the OP use and which processors and modes are supported by the emulator. If you are irritated by the "x86", then edit it away (in my post and also the tag) :-) – rkhb Sep 17 '15 at 16:47
  • @rkhb: It's definitely x86. There's no way to sweep x86's long and sordid history under the rug. :P My complaint is that some people don't specify which way they're using x86, and think x86 asm means 16bit DOS, and leave out that tag and info in their question. Thanks for the info that TASM usually means 16bit DOS. I also added a DOS tag. – Peter Cordes Sep 17 '15 at 16:52
  • I have Turbo Assembler 1.0 (TASM) on my shelf (it came with Turbo C 2.0). TASM Version 1.0 to 3.0 could produce 386 code, but the assembler itself was 16 bit. TASM 4.0 and later came with assemblers that ran as 32bit application (tasm32). There was no TASM 1.4 by Borland but to make matters confusing there is a **TASM installer 1.4** for Windows that installs a minimalist version of TASM 3.0.That installer is [here](http://sourceforge.net/projects/tasmforwindows/) . **TASM Installer 1.4** comes with a DOSBox image and a somewhat stripped down version of **Turbo Debugger 3.1** and **TASM 3.0**. – Michael Petch Sep 17 '15 at 18:39
  • 1
    @MichaelPetch: Thanks. I didn't know the existence of that TASM "1.4". The TASM that is known as TASM-5 declares itself as "Turbo Assembler Version 4.1 Copyright (c) 1988, 1996 Borland International". – rkhb Sep 17 '15 at 19:14
  • @rkhb : That is true about TASM 5.0 with regards to TASM.EXE (It shows as 4.1 when run), but I seem to recall if you ran TASM32.EXE (The 32 bit version) it showed as 5.0. What I don't really know is if TASM.EXE actually changed much or if Borland released it with the wrong banner. But definitely a point of confusion. – Michael Petch Sep 17 '15 at 19:37