我必须编写一个找到两个数字的GCD的程序,提示符如下所示。 "你要编写一个包含函数的程序,该函数将使用欧几里德算法评估最大公约数函数,定义如下:
GCD(a,0) = a
GCD(a,b) = GCD(b, a mod b) for b > 0
你的功能是递归计算GCD(a,b)并返回ax中的值。应该通过按下堆栈上a和b的值来完成对函数的输入。
您的主程序将:
在屏幕上打印程序说明 在屏幕上显示提示 从键盘接受a和b的值(使用您之前编写的DEC_IN过程。) 将a和b的值传递给函数 使用适当的提示打印出GCD(a,b)的值(使用您之前编写的DEC_OUT过程。) 询问用户是否希望重复该过程。" 我相信我已经完成了大部分目标但是在运行我的程序时只需在输入第二个整数后冻结。 任何帮助将不胜感激 这是我的代码:
; program to calculate gcd of two inputs
org 100h
section .data
prompt0: db "This is a program to caculate the GCD of two inputs $"
prompt1: db "Please enter integer X: $"
prompt2: db "Please enter integer Y: $"
prompt3: db "The GCD is: $"
intX dw 0
intY dw 0
gcd dw 0
section .text
mov ah,9 ; print prompt
mov dx,prompt0
int 21h
mov ah,9 ; print prompt
mov dx,prompt1
int 21h
call dec_in ; read value into bx
mov [intX], bx
mov ah,9 ; print prompt
mov dx,prompt2
int 21h
call dec_in ; read value into bx
mov [intY], bx
call calc_GCD
mov bx, [gcd]
mov ah,9 ; print output label
mov dx,prompt3
int 21h
call dec_out ; display the value in bx (gcd)
dec_in:
; save registers
push ax
push dx
xor bx,bx ; bx holds accumulated input
mov ah,1 ; read char fcn
int 21h ; read it into al
while1:
cmp al,0Dh ; char = CR?
je finis ; if so, we are done
push ax ; save the character read
mov ax,10 ; set up for multiply
mul bx ; dx:ax <- bx * 10
mov bx,ax ; put 16-bit result back in bx (assume no overflow)
pop ax ; restore the char read
and ax,000Fh ; convert character '0'-'9' to value 0-9
add bx,ax ; add value to accumulated input
mov ah,1 ; read char fcn
int 21h ; read next char into al
jmp while1 ; loop until done
finis:
; restore registers
pop dx
pop ax
ret
dec_out:
; save registers we will be using
push ax
push bx
push cx
push dx
xor cx,cx ; cx counts digits, initially zero
rept:
mov ax,bx ; set up to divide by by 10
xor dx,dx ; must have a 32 bit (unsigned) dividend
mov bx,10 ; divisor will be in bx
div bx ; quotient will be in ax, remainder in dx
push dx ; push remainder on stack
inc cx ; we generated another digit, so count it
mov bx,ax ; the quotient goes back in bx
cmp ax,0 ; clever way to test if quotient is zero
jne rept ; if not, generate next digit
mov ah,2 ; display character function
for2: ; loop cx times
pop dx ; pop digit to print
or dl,30h ; convert the digit to print to ASCII code
int 21h ; display the character
loop for2 ; and keep going until all digits displayed
; restore registers
pop dx
pop cx
pop bx
pop ax
ret
calc_GCD:
mov ax, [intY]
cmp ax, 0
jne chk_swap ; check if swap is needed
mov ax, [intX]
mov [gcd], ax ; move result into gcd
ret
chk_swap:
mov ax, [intX] ;store
mov bx, [intY]
cmp ax, bx
jl swap
jnl loop
swap:
mov ax, [intX]
mov bx, [intY]
;temp
mov cx, [intY]
; intY = intX
; intX = temp
mov bx, ax
mov ax, cx
mov [intX], ax
mov [intY], bx
jmp loop
loop:
mov dx, [intX]
shr dx, 16
mov ax, [intX]
mov bx, [intY]
div bx
mov di, [intX]
mov si, [intY]
mov di, si
mov [intX], di
mov [intY], dx
jmp calc_GCD
答案 0 :(得分:1)
没有必要换掉GCD。如果除数大于被除数,则商为零,余数为被除数,因此如果需要,GCD的第一步将自动进行交换。
无需将中间结果存储到intX和intY中。只需使用寄存器来计算GCD,直到得到0的余数,然后前一个余数就是GCD。
; ;ax, bx contain the two numbers
gcd0: xor dx,dx ;divide
div bx
mov ax,bx ;ax = new dividend = old divisor
mov bx,dx ;bx = new remainder
test bx,bx ;loop if remainder != 0
jnz gcd0
; ;ax = gcd
最大循环数是Fibonacci数:46368,28657,gcd = 1