2014-11-12 2 views
1

GCD를 찾기위한 어셈블리 프로그램을 만들고, 두 개의 정수를 취해서 GCD를 출력하고 있습니다.어셈블리 GCD 코딩 무한 루프

;Title - GCD 

INCLUDE Irvine32.inc 


.data 

strA BYTE "Enter an integer A: ",0 
strB BYTE "Enter an integer B: ",0 
temp DWORD ? 
finalStr BYTE "GCD of the two integers is: ",0 



.code 

main PROC 

call Clrscr 

mainLoop: 
mov edx,OFFSET strA 
call WriteString 
call ReadInt 
mov temp, eax 
call Crlf 

mov edx, OFFSET strB 
call WriteString 
call ReadInt   
mov ebx, eax 
mov eax, temp 
call Crlf 

call GCD 

mov edx, OFFSET finalStr 
call WriteString 
call WriteInt 

call WaitMsg 

jmp mainLoop 

main ENDP 

;----------------------------------------------- 
abs PROC 
; Computes the absolute value of a number. 
; Receives: eax = the number 
; Returns: eax = absolute value of the number 
;----------------------------------------------- 
    cmp eax, 0     ; see if we have a negative number 
    jge done 
    neg eax 

done: 
    ret 
abs ENDP 

;----------------------------------------------- 
gcd PROC 
; Finds Greatest Common Divisor of two integers 
; Recieves: eax= int A , ebx = int B 
; Returns eax = GCD 
;----------------------------------------------- 
call abs  ;takes absolute value of both registers 
mov temp, eax 
mov eax, ebx 
call abs 
mov eax, temp 

cmp eax, ebx ; making sure we divide the bigger number by the smaller 
jz DONE  ; if numbers are equal, GCD is eax either way 
jc SWITCH ;swaps if ebx is larger then eax 

mov edx, 0 

SWITCH:   ;swaps values so eax is larger then ebx 
mov temp, eax 
mov eax, ebx 
mov ebx, temp 
mov edx, 0 
jmp L1 

L1:  ;divides until remainder is 0, then eax is GCD 
div ebx 
cmp edx, 0 
jz DONE 
mov eax, edx 
jmp L1 


DONE: 
gcd ENDP 

END main 

어떻게이 루프에서 얻을 수 있습니다 : 두 정수가 제출 된 후이 코드는, 그러나 프로그램이 무한 루프에 잘 걸리면 어셈블?

call abs  ;takes absolute value of both registers 
mov temp, eax 
mov eax, ebx 
call abs 
mov eax, temp 

거기 abs 다시 ebxebx 값을 -ed 이동 아무것도 없다, 그것이 있어야 :

+0

PROC 'gcd'가 반환되지 않습니다. 'DONE :'과'gcd ENDP' 사이에'ret'를 삽입하십시오. 'div' 전에 매번'EDX'를 지우는 것을 잊지 마십시오. 유클리드 알고리즘의 구현이 잘못되었습니다. – rkhb

답변

1

나는 똑바로 하나 문제가 볼

call abs  ;takes absolute value of both registers 
mov temp, eax 
mov eax, ebx 
call abs 
mov ebx, eax 
mov eax, temp 

또 다른 문제 , 귀하의 문제와 직접 관련이있는 것은 아니지만, x86 아키텍처는 길이가이고 코드를 크게 정리하는 xchg 명령어가 있습니다. 구체적으로는 temp을 사용합니다.


그리고 생각에 대한 순서 :

cmp eax, ebx ; making sure we divide the bigger number by the smaller 
jz DONE  ; if numbers are equal, GCD is eax either way 
jc SWITCH ;swaps if ebx is larger then eax 

mov edx, 0 

SWITCH:   ;swaps values so eax is larger then ebx 

당신은 SWITCH:의 코드에 관계없이 값이 큰있는를 실행 위하여려고하고 있다는 것을 확인할 수 있습니다.

당신은 변경하여이 문제를 해결할 수 있습니다 :

jc SWITCH ; swaps if ebx is larger then eax 

mov edx, 0 

로 : 그 너머


jc SWITCH ; swaps if ebx is larger then eax 

mov edx, 0 
jmp L1 
, 내가 얻을 당신의 머리
에 해당 코드 를 실행 실제로 제안하는거야 어떻게 작동하는지에 대한 이해, 그러나 더 중요한 것은, 당신이 더 나은 개발자가되는 그런 방식으로 기계처럼 생각하는 법입니다. 다음 표와

시작 :

[temp] eax  ebx  edx  <stack> 
-------- -------- -------- -------- -------- 
?  ?  ?  ?  ?, 

그런 다음, 차례로 각 라인을 실행 데이터의 변경 열에 작성합니다.

문제가 어디에서 오는 당신은 결국 알아낼 수 있습니다 만 이 디버깅을 의미했다 때로는 오래된 사람이

:-) 그것은 훨씬 더 나은 이유도 이해하게 될 것입니다

나는 단서를 줄 것이다. edx을 계속 주시하고 어떻게 변화하는지, 그리고 036에 따라 달라질 수있는 div과 같은 다른 특정 명령어에 어떤 영향을 줄 수 있는지 확인하십시오.

+0

감사합니다.그러나, 나는 아직도이 루프에 걸려있다. – GeorgeO

+0

그래, @ George, 나는 아직도 그것을 조사하고있다 :-) – paxdiablo

+0

그래, 나는 게시 한 후 조금 더 알아 차렸다. 그래서 "mov edx, 0"줄 아래에 "jmp L1"을 추가 했으므로 스위치를 건너 뛸 수있다. 여전히 루프를 얻고있다 – GeorgeO