Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 用x86汇编语言查找GCD的程序_Assembly_Nasm_Dos - Fatal编程技术网

Assembly 用x86汇编语言查找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,提示是这样的。 “您要编写一个包含函数的程序,该函数将使用欧几里德算法计算最大公因式函数,定义如下:

      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个字节