2017-01-21 1 views
1

아래와 같이 어셈블리 코드를 만들었습니다. 문제는 프로그램을 실행할 때 "상대 점프가 범위를 벗어났습니다."라는 오류 메시지가 나타납니다. 문제는 루프의 내용이 너무 길다는 것입니다. 누군가 나를 도울 수 있고 루프을 변경하는 방법을 알려줄 수 있습니까?어셈블리 - 상대 점프가 범위를 벗어남

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 

답변

3

불필요한 작업을 시작하십시오. 예를 들어 여기에서 실제로 달성하려는 내용이 확실하지 않지만 한 번에 많은 경우에 mov [print], <value>이 반복적으로 나타나는 것으로 나타납니다. 모든 초기 선회에도 불구하고 항상 mov [print],dl이 발생합니다. 이 경우 나머지 코드는 모두 제거해야 코드에서 4 바이트 이상의 멀티 바이트 연산을 제거 할 수 있습니다.

loop 문을 사용하지 않아도이 문제를 해결할 수 있습니다. 대신, 자신을 카운터의 값을 확인하고 사용하십시오 jmp :

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

이 거의 점프보다는 loop 효과적으로 사용하는 것입니다 짧은 점프를 할 수 있습니다. loop이 구현하는 짧은 점프는 루프 명령의 -128 및 +127 바이트 내에 있어야합니다.

+0

도움을 주셔서 대단히 감사합니다. –

+1

동일한 범주의 "불필요한 작업"에서 'cmp cx, 0'을 제거 할 수 있습니다. 예제에서 명령. 'dec cx '는 이미 필수 플래그를 설정합니다! – Fifoernik

+0

그리고 이것이 실제 8086 코드가 아니라면 반대 조건부 점프'jnz loop1'을 쓰면 더 명확 해집니다. (1 점 덜 떨어짐) – Fifoernik