GCD 递归汇编语言 X86 MASM

发布于 2024-12-12 00:53:51 字数 1574 浏览 0 评论 0原文

感谢大家的帮助,我做了一些非常好的更改,但现在它给我的第一组值的答案是+4198498,而不是 5,我知道这是错误的。我是否推送了错误的内容或没有正确弹出注册表?我使用 ret 8 清理了堆栈,它应该清理下一次调用的堆栈,对吗?

这是我到目前为止所拥有的:

TITLE MASM GCD                      (GCD.asm)


; Description:GCD recursive
; 
; Revision date:

INCLUDE Irvine32.inc
.data
myMessage BYTE "Assignment 7 GCD Recursive style",0dh,0ah,0
myMess2   BYTE "GCD = " ,0dh,0ah,0


;first set of nums
val1 DWORD  5
val2 DWORD  20

;second set of nums
val3 DWORD  24
val4 DWORD  18

;3rd set
val5 DWORD  11
val6 DWORD  7

;4th set
val7 DWORD  432
val8 DWORD  226

;5th set
val9 DWORD  26
val10 DWORD  13

.code
main PROC
    call Clrscr  

    mov  edx,offset myMessage
    call WriteString        ;write message
    call Crlf               ;new line
    push val1
    push val2
    call GCD

    exit
main ENDP

;------------------------------------------------
GCD PROC,
; This finds GCD
; Gets values from stored values
;returns NA

;------------------------------------------------

        xor edx,edx
        mov eax,dword ptr[esp+8] ;dividend
        mov ebx,dword ptr[esp+4] ;divisor
        div ebx              ;eax/ebx
        cmp  edx,0           ;remainder in edx
        je   L1              ;yes: quit
        call GCD             ;no: call GCD agian
    L1:
        mov eax,ebx          ;move the divisor into eax for printing i.e GCD    
        mov  edx,offset myMess2
        call WriteString
        call WriteInt        ;Display GCD WriteInt uses EAX = qutent
        call crlf
        ret 8                ;clean up the stack
GCD ENDP

END main

Thank everyone for the help I have made some really good changes but now it gives me an answer of +4198498 instead of 5 for the first set of values which I know is wrong. Did i push something wrong or did not pop a reg correctly? I cleaned up the stack right by using the ret 8 which should clean up the stack for the next call is that right?

Here is what I have so far:

TITLE MASM GCD                      (GCD.asm)


; Description:GCD recursive
; 
; Revision date:

INCLUDE Irvine32.inc
.data
myMessage BYTE "Assignment 7 GCD Recursive style",0dh,0ah,0
myMess2   BYTE "GCD = " ,0dh,0ah,0


;first set of nums
val1 DWORD  5
val2 DWORD  20

;second set of nums
val3 DWORD  24
val4 DWORD  18

;3rd set
val5 DWORD  11
val6 DWORD  7

;4th set
val7 DWORD  432
val8 DWORD  226

;5th set
val9 DWORD  26
val10 DWORD  13

.code
main PROC
    call Clrscr  

    mov  edx,offset myMessage
    call WriteString        ;write message
    call Crlf               ;new line
    push val1
    push val2
    call GCD

    exit
main ENDP

;------------------------------------------------
GCD PROC,
; This finds GCD
; Gets values from stored values
;returns NA

;------------------------------------------------

        xor edx,edx
        mov eax,dword ptr[esp+8] ;dividend
        mov ebx,dword ptr[esp+4] ;divisor
        div ebx              ;eax/ebx
        cmp  edx,0           ;remainder in edx
        je   L1              ;yes: quit
        call GCD             ;no: call GCD agian
    L1:
        mov eax,ebx          ;move the divisor into eax for printing i.e GCD    
        mov  edx,offset myMess2
        call WriteString
        call WriteInt        ;Display GCD WriteInt uses EAX = qutent
        call crlf
        ret 8                ;clean up the stack
GCD ENDP

END main

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

記柔刀 2024-12-19 00:53:51

首先,我发现了一些错误和坏习惯:

GCD PROC,
    dividend:DWORD,
    divisor:DWORD

在我看来为程序声明局部变量是一个坏习惯。 (来自高级语言的结果)

您需要将其放入数据段中。此外,还有一个语法错误,双字未初始化,因此您应该这样声明它们:

.DATA ?
dividend  dword ?
divisor dword ?

div 指令的寄存器也有问题:

xor edx,edx
mov eax,xxx ;dividend
mov ebx,yyy ;divisor
div ebx     ;eax/ebx
cmp  edx,0  ;remainder in edx

现在要使用您的值集并划分它们,您有不同的选择:

1-移动它们手动将它们一一放入寄存器中

mov eax,dword ptr[val01] ;dividend
mov ebx,dword ptr[val02] ;divisor

2-将它们直接压入堆栈(如函数参数)

push val01
push val02
call GDC

;in GDC proc
mov eax,dword ptr[esp+8]
mov ebx,dword ptr[esp+4]

3-将它们放入“数组”中并循环遍历它们

exercise for you

First I see a few errors and bad habits:

GCD PROC,
    dividend:DWORD,
    divisor:DWORD

Declaring local variables for your procedures is a bad habit in my opinion. (result from high level languages)

You need to put that in your data segment. Additionally there's a syntax error, the dwords are uninitialized thus you should declare them like this:

.DATA ?
dividend  dword ?
divisor dword ?

You also have a problem with the registers for the div instruction:

xor edx,edx
mov eax,xxx ;dividend
mov ebx,yyy ;divisor
div ebx     ;eax/ebx
cmp  edx,0  ;remainder in edx

Now to use your sets of values and divide them you ave different choices:

1-move them manually 1 by 1 in your registers

mov eax,dword ptr[val01] ;dividend
mov ebx,dword ptr[val02] ;divisor

2-you push them directly on the stack (like function parameters)

push val01
push val02
call GDC

;in GDC proc
mov eax,dword ptr[esp+8]
mov ebx,dword ptr[esp+4]

3-put them in an "array" and loop through them

exercise for you
静若繁花 2024-12-19 00:53:51

我看到的一些事情(忽略计算是否正确):

    mov edx,dividend            ;this is value 1    
    mov ebx,divisor         ;this is the divider make sure its smaller number!    
    div ebx                  ;divide int1 by int2

DIV ebxEDX:EAX 除以 EBX,因此您应该移动被除数到EAX并清除EDX

    cmp  edx,0               ;does remainder = 0 ?
    je   L1                  ;yes: quit

    call GCD             ;no: call GCD agian

您在哪里设置此调用的参数?

  L1:
    mov eax,ebx          ;EAX = GCD

这里你用除数覆盖商是故意的吗?

    pop edx
    pop ebx

我不明白你把这些寄存器推到哪里。这是由 MASM 自动完成的吗?如果没有,你需要推动他们。

A few things I see (ignoring whether the calculation is right):

    mov edx,dividend            ;this is value 1    
    mov ebx,divisor         ;this is the divider make sure its smaller number!    
    div ebx                  ;divide int1 by int2

DIV ebx divides EDX:EAX by EBX, so you should move the dividend to EAX and clear EDX.

    cmp  edx,0               ;does remainder = 0 ?
    je   L1                  ;yes: quit

    call GCD             ;no: call GCD agian

Where are you setting up the parameters for this call?

  L1:
    mov eax,ebx          ;EAX = GCD

Here you overwrite the quotient with the divisor is that intentional?

    pop edx
    pop ebx

I don't see where you push these registers. Is that done automatically by MASM? If not you need to push them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文