2015-09-14 60 views
1

我目前正在做一项任务,虽然前两项要求没有问题,但现在我遇到了最后一个问题。它要求我们使用UDP(称为MultiplyNumbers)来查找用户(整数)提供的输入的功能。它调用AddNumbers,并使用循环来查找总和。 CalculatePower然后调用MultiplyNumbers,这样做n次(根据输入)我已经得到了它的小数字,如2^3或5^2,但是当我把它,如10^5,它工作咳出一个错误的答案。我不确定我在这里搞砸了什么,但任何见解都会很棒。发现用户输入的力量

这是我的代码。

INCLUDE Irvine32.inc 


    .data 
str1 BYTE "Enter a positive integer: ",0 
str2 BYTE "The sum is: ",0 
str3 BYTE "The product is: ",0 
str4 BYTE "The power result is: ",0 
num1 DWORD 0 
num2 DWORD 0 
sum DWORD 0 
prod DWORD 0 
pow DWORD 0 
temp DWORD 0 // used for counting loop in MultiplyNumbers 
count DWORD 0 // used for indexing loop in CalculatePower 

    .code 
main PROC 

    call GetInteger;   // Getting input 
    mov num1, eax; 
    call GetInteger; 
    mov num2, eax; 



    mov eax, num1;   // Calculations 
    mov ebx, num2; 
    call AddNumbers;  
    mov edx, OFFSET str2 ; 
    mov eax, sum; 
    call displayResults 

    mov eax,num2; 
    mov temp,eax; // indexing loop counter 
    xor eax,eax; 
    call MultiplyNumbers; 
    mov edx, OFFSET str3; 
    mov eax, prod; 
    call displayResults 

    call CalculatePower; 
    mov edx, OFFSET str4; 
    call WriteString; 
    mov eax, pow; 
    call displayResults 

    invoke ExitProcess, 0 

main ENDP 

GetInteger PROC 
    ;----------------------------------------------------- 
    ; Displays the results of previous procedure 
    ; Receives: 
    ; Returns: nothing 
    ;----------------------------------------------------- 

    mov edx, OFFSET str1; 
    call WriteString; 
    call ReadInt; 
    ret 
GetInteger ENDP 

AddNumbers PROC 
    ;----------------------------------------------------- 
    ; Displays the results of previous procedure 
    ; Receives: 
    ; Returns: nothing 
    ;----------------------------------------------------- 
    add eax, ebx; 
    mov sum, eax; 
    ret 
AddNumbers ENDP 

MultiplyNumbers PROC 
    ;----------------------------------------------------- 
    ; Calculates the multiplication of the intgers provided by the user. 
    ; Receives: 
    ; Returns: nothing 
    ;----------------------------------------------------- 
    mov ebx, num1; 
    mov ecx, temp; // setting the loop counter; 
    MultiLoop: 
    call AddNumbers; 
    loop MultiLoop; 
    mov prod, eax; 
    ret 
MultiplyNumbers ENDP 

CalculatePower PROC  
    ;----------------------------------------------------- 
    ; Calculates the power of the intger provided by user 
    ; Receives: 
    ; Returns: nothing 
    ;-----------------------------------------------------   

    mov eax,num2 
    mov count,eax; // used to count for powerLoop 
    mov eax,num1; 
    mov temp,eax; // setting the count for the multiplication loop 
    xor eax,eax; // clearing eax 

    powerLoop: 
    call MultiplyNumbers; 
    dec count; // decreasing count for powerLoop 
    mov ecx,count; // moving decreased count to index for power loop; 
    loop PowerLoop; 
    mov pow, eax; 
    ret 
    CalculatePower ENDP 



    displayResults PROC 
    ;----------------------------------------------------- 
    ; Displays the results of previous procedure 
    ; Receives: 
    ; Returns: nothing 
    ;----------------------------------------------------- 

call WriteString  ; display string 
call WriteInt   ; display sum 
call crlf   ; advance to next line 
ret 
DisplayResults ENDP 


END main 
+0

而不是'X^Y',你似乎在计算类似'(X^2)*(Y-1)'的东西。对于2^3和5^2来说,可以达到正确的结果,但不是10^5。 – Michael

回答

0

我们来分析一下你的函数

  • AddNumbers资金EAX和EBX并将结果保存在sum
  • MultiplyNumbers不设置EAX入境,但设置EBX到num1和ECSX到temp。因此,它实现了计算:EAX+num1*temp和结果存储在prod EAX
  • CalculatePowercountnum2,设置tmpnum1和EAX为0。然后调用MultiplyNumberscount-1倍(因为你移动到ECX之前递减count由LOOP递减)。所以它计算:第一次迭代时为0+num1*num1,第二次迭代时为EAX+(num1*num1) = (0+num1*num1)+(num1*num1),依此类推。

所以整个计算都是错误的,计算结果是:num1^2*(num2-1)

恰好当num1=2num2=3然后2^2*(3-1)==2^3。但这是纯粹的运气。计算错误。

潜在的解决方案

与您的代码的问题是全局变量的依赖传递参数的功能。编写汇编函数时没有副作用的常用方法是:

  1. 要依赖传递给堆栈和被调用者的参数来保存寄存器值。
  2. 若要使用一些定义的寄存器来传递参数,并且调用者将这些寄存器保留在堆栈上。

您也可以将两者混合,例如总是考虑一些寄存器将通过一个函数调用(EAX例如)被销毁,来电保存它。并且考虑一些其他寄存器必须由被调用者保存。

+0

哇。我觉得自己像个白痴。我认为我最大的问题是我过度思考一切。我倾向于这样做。谢谢你的帮助,fjardon,我明白了,你的文章帮了我很多。我一直忘记组装非常简单,我需要停止让复杂的东西。如果你曾经在亚特兰大,我会给你买一瓶啤酒! – srallen87

+0

@ srallen87我很高兴它帮助:)只是有一点提醒,因为我看到你是新的网站,向其他人展示一个答案是有用的,你可以upvote它。如果它解决了你的问题,你可以*接受它作为答案*。 – fjardon