1
votes

I've made an assembly code as shown below. The problem is that when I run the program, an error message appears: "relative jump out of range". The problem is that the content of the loop is too long. Can someone help me and tell me how to change the loop in order it will work?

IDEAL
MODEL small
STACK 100h
INCLUDE 'gvahim.mac'

DATASEG
; --------------------------
pos_dig_7 db 0
pos_div_7 db 0
print db 0
index db 0
ARR_DIV_7 db 100 dup(?)
ARR_DIGIT_7 db 100 dup(?)
; --------------------------
CODESEG
start:
    mov ax, @data
    mov ds, ax
; --------------------------
    mov cx, 100
    loop_1:
        mov [print], 0
        inc [index]
        mov ax, 0
        mov al, [index]
        mov bl, 7
        div bl
        cmp ah, 0
        jne jump1
        mov [print], 1
        mov bx, 0
        mov bl, [pos_div_7]
        mov bl, [index]
        mov [ARR_DIV_7+bx], al
        inc [pos_div_7]
            jump1:
                mov ax, 0
                mov al, [index]
                mov bl, 10
                div bl
                cmp al, 7
                jne jump2
                mov [print], 2
                jump2: 
                    cmp ah, 7
                    jne jump3
                    mov [print], 2  
                        jump3:
        mov [print], dl
        cmp dl, 0
        jne next1
        mov ax, 0
        mov al, [index]
        jmp end_of_pro
        next1: 
            cmp dl, 1
            jne next2
            mov ax, 77
            next2:
                cmp dl, 2
                jne end_of_pro
                mov bx, 0
                mov bl, [pos_dig_7]
                mov al, [index]
                mov [ARR_DIGIT_7+bx], al
                inc [pos_dig_7]
                mov ax, 777
        end_of_pro:
        call PRINT_NUM_DEC
        call NEW_LINE
    loop loop_1
; --------------------------
exit:

    mov ax, 4c00h
    int 21h
INCLUDE 'gvahim.asm'

END start
1

1 Answers

3
votes

Begin by moving unnecessary operations. For instance, it's unclear what you're actually trying to accomplish here, but at a glance it appears that you mov [print], <value> repetitively in a number of cases. Despite all of the initial gyrations, it appears that mov [print],dl will always happen. If that's the case, remove all of the rest of them, which eliminates at least four multi-byte operations from your code.

You could also get around this issue by avoiding the loop statement. Instead, check the value of the counter yourself and use a jmp:

dec  cx
cmp  cx, 0        ; Not actually needed - preceding line will set ZF at zero
jz   finished
jmp  loop1
finished:
<code continues>

This allows a near jump rather than a short jump, which is what loop is effectively using. A short jump, which loop implements, must be within -128 and +127 bytes of the loop instruction