Assembly 用x86汇编语言查找GCD的程序
编辑:代码现在运行,感谢您的帮助。它可能不漂亮,但它是有效的 我必须写一个程序,找到两个数字的GCD,提示是这样的。 “您要编写一个包含函数的程序,该函数将使用欧几里德算法计算最大公因式函数,定义如下:Assembly 用x86汇编语言查找GCD的程序,assembly,nasm,dos,Assembly,Nasm,Dos,编辑:代码现在运行,感谢您的帮助。它可能不漂亮,但它是有效的 我必须写一个程序,找到两个数字的GCD,提示是这样的。 “您要编写一个包含函数的程序,该函数将使用欧几里德算法计算最大公因式函数,定义如下: GCD(a,0) = a GCD(a,b) = GCD(b, a mod b) for b > 0 您的函数是递归计算GCD(a,b)并返回ax中的值。函数的输入应通过在堆栈上推送a和b的值来完成 你的主要计划是: 在屏幕上打印程序说明 在屏幕上显示提示 从键盘
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
;用于计算两个输入的gcd的程序
组织100小时
第二节数据
prompt0:db“这是一个计算两个输入的GCD$的程序”
prompt1:db“请输入整数X:$”
prompt2:db“请输入整数Y:$”
提示3:db“GCD为:$”
intX dw 0
intY dw 0
gcd dw 0
第节.案文
mov-ah,9岁;打印提示
mov dx,prompt0
int 21h
mov-ah,9岁;打印提示
mov dx,提示1
int 21h
打电话给dec_;将值读入bx
mov[intX],bx
mov-ah,9岁;打印提示
mov dx,prompt2
int 21h
打电话给dec_;将值读入bx
mov[intY],bx
呼叫calc_GCD
mov bx,[gcd]
mov-ah,9岁;打印输出标签
mov dx,prompt3
int 21h
把dec_叫出去;以bx(gcd)显示值
十二月份:
; 保存寄存器
推斧
推送dx
异或bx,bx;bx保存累积输入
mov-ah,1;读字符fcn
int 21h;把它读给艾尔听
第1部分:
cmp-al,0Dh;char=CR?
杰菲尼斯;如果是这样,我们就完了
推斧;将字符保存为已读
mov-ax,10;设置为乘法
mul-bx;dx:ax没有必要交换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
循环的最大数量是斐波那契数:4636828657,gcd=1您是否使用调试器进行了调试?Turbo调试器工作得非常好,但您也可以使用debug.exe(DOS调试器);存储
jl交换
紧接着是jnl循环
并不表示工艺高超。删除jl-swap
jmp-loop
,紧接着删除loop:
,这也不意味着高超的工艺。这段代码存在足够多的问题,我怀疑提供工作代码是否是您了解所需内容的最佳解决方案。我认为这个问题和代码更适合让一名助教或一名教授坐下来,告诉你需要理解的课程材料,以便正确重写代码。使用测试bx,bx
,而不是或bx,bx
。太可怕了@这是旧的8088代码。这会对8088处理器产生影响吗?我更改了答案。@rcgldr:在8088/8086上,它们都是reg、reg的3个时钟周期,并且都编码为2个字节