2011-10-23 108 views
1

感谢大家的帮助我做出了一些非常好的改变,但现在它给了我一个+4198498而不是5的答案,我知道第一组值是错误的。我推错了什么或没有正确弹出一个reg?我通过使用ret 8清理堆栈,应该为下一次调用清理堆栈是正确的?GCD递归汇编语言X86 MASM

这是我到目前为止有:

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 

回答

0

首先,我看到了一些错误和不良的生活习惯:

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 

现在用你的套值的和除以他们你AVE不同的选择:

手动1在寄存器1-移动他们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 
0

有几件事情我看到(忽略的计算是否正确):

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自动完成的吗?如果没有,你需要推他们。