我正在尝试制作一个用于查找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
如何摆脱这种循环?
答案 0 :(得分:1)
我直接看到一个问题:
call abs ;takes absolute value of both registers
mov temp, eax
mov eax, ebx
call abs
mov eax, temp
没有什么可以将abs
- ebx
值移回ebx
,它应该是:
call abs ;takes absolute value of both registers
mov temp, eax
mov eax, ebx
call abs
mov ebx, eax
mov eax, temp
另一个问题,虽然与您的问题没有直接关系,但是x86
架构 long 有一条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
,看看它是如何变化的,以及它可能如何影响某些其他指令,例如div
,这可能取决于它是否为零。< / p>