【发布时间】:2016-03-06 04:36:51
【问题描述】:
编辑:代码现在运行,感谢您的帮助。它可能不漂亮,但它有效
我必须编写一个程序来查找两个数字的 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
【问题讨论】:
-
你用调试器单步执行了吗? Turbo 调试器运行良好,但您也可以使用 debug.exe(DOS 调试器)。
-
mov eax, [intX] ;store -
jl swap后面紧跟jnl loop并不代表精湛的工艺。删除jl swap。 -
jmp loop后面紧跟loop:也不代表精湛的工艺。 -
这段代码有很多问题,我怀疑给你工作代码是你学习所需内容的最佳解决方案。我认为这个问题和代码更适合让您的班级有助教或教授坐下来,并指出您需要理解的课程材料才能正确地重写代码。