2015-01-11 2 views
1

이 코드 (having a string of length n, build another of length n-2 as it follows: sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3)가 있는데 왜 멈추는 지 알 수 없습니다. 오류가없고 잠시 동안 디버깅을 해왔지만 알고리즘에 문제가 있는지 파악할 수 없습니다.x86 프로그램 고정 [tasm]

prints macro number 
local decompose, pops 
    mov bx,10 
    mov al, number 
    mov cx,0 
    decompose: ;pushing digits to the stack 
     inc cx 
     mov ah,0 
     div bl 
     mov dl,ah ; remainder - last digit 
     add dx,48 ; to transform it in its char version 
     push dx 
     cmp al,0 
     jnz decompose 
    pops:    ; pop digits off the stack 
     pop dx 
     mov ah,2h 
     int 21h 
    loop pops 
     ; pretty spacing 
     mov dl,' ' 
     mov ah,2h 
     int 21h 

endm 

data segment para public 'data' 
    sir db 5, 10, 12, 4, 3 
    n equ $-sir 
    sir2 db n-2 dup(0) 
data ends 

code segment para public 'code' 
start proc far 
    assume cs:code,ds:data 
    push ds 
    xor ax,ax 
    push ax 
    mov ax,data 
    mov ds,ax 

    mov si,0 
    mov dx,3 
    mov cx,n 
    sub cx,2 

l1: 
    mov ah,0 
    mov al,sir[si] 
    add al,sir[si+1] 
    add al,sir[si+2] ;sum of 3 numbers 
    div dx     ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3 
    mov sir2[si],al 
    inc si 
    cmp si,cx 
jbe l1 

    mov si,0 
l2: 
    prints sir2[si] 
    inc si 
loop l2 

ret 
start endp 
code ends 
end start 

아무도 도와 줄 수 있습니까?

+1

왜 얼어 있었는지, 어디서 붙어 있었는지 알기 위해 어떤 노력을 했습니까? 즉 ** ** 코드를 디버깅 했습니까? 이 사이트는 무료 디버깅 서비스가 아니므로 귀하의 질문이 의미하는 바와 같이, 그것은 아마도 오프 주제로 마감 될 것입니다. –

+0

예 + 나는 jmp로 바꿨을 때 루프에 달라 붙었다 고 생각했습니다. –

+1

* 분해 * 루틴 내에서 CX를 삭제했습니다. 'mov cx, 0'을'mov ah, 0'으로 변경하십시오. –

답변

1

변경

div dx     ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3 

(마이클의 답변을 참조)

div dl     ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3 

합니다.

매크로는 매크로가 호출 된 위치에 "있는 그대로"삽입되는 코드 조각입니다. 매크로 printsloop l2에 손댈 필요가없는 CX으로 변경됩니다. 루프를 다시 작성 :

mov si, 0 
    mov di, cx 
l2: 
    prints sir2[si] 
    inc si 
    dec di 
    jnz l2 

BTW : 스택을 정의하는 것을 잊지 마세요 :

_STACK SEGMENT PARA STACK 'STACK' 
    dw 1024 dup (?) 
_STACK ENDS 
+0

'cmp si, n-2'를 쓸 수 있습니까? –

+0

@ LorenaSfăt : 예. TASM은 컴파일시'n-2 '를 상수로 변환합니다. – rkhb

+0

그래, 이제는 올바른 값이 아닌 일부 값을 출력하기 때문에 알고리즘이어야한다고 생각했습니다. –

1

DIV r/m16 대한 설명"r/m16함으로써 부호 분할 DX:AX"이다. 즉, 분자는 DXAX의 비트에 의해 형성된 32 비트 값입니다.
몫이 너무 커서 AX에 들어 가지 않으면 예외가 발생합니다. 이를 방지하려면 나누기 전에 DX을 삭제해야합니다 (즉, mov dx,0 또는 xor dx,dx). 분명히 이것은 또한 DX을 분모로 사용할 수 없다는 것을 의미합니다.

1

너무 많은 반복을하고 있기 때문에 프로그램이 동결 수도 있습니다! SIR2 저장소의 3 바이트를 갖는다

cmp si,cx 
jbe l1 

이 4 번 반복 준다! 사용 jb l1

+0

그게 좋겠다. 나는 여러분 모두가 말했던 것과 지금 가치 (올바른 것이 아닌)를 인쇄하고 나서 그것을 얼입니다. –

+0

이 프로그램을 단순한'ret'에서 끝내고 싶다면'push ds'와'push ax' 명령을 제거해야합니다. 또는 프로그램의 마지막 단계로'mov ah, 4Ch'와'int 21h'를 사용하십시오. –

+0

하지만 선생님은 .exe 프로그램의 본문 중 일부라고 말씀 하셨고 그대로 받아 들여야한다고 말씀하셨습니다./ –

관련 문제