2015-09-14 55 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