View Single Post
Old Mar 31st, 2008, 7:28 PM   #7
Fall Back Son
Professional Programmer
 
Join Date: Oct 2006
Posts: 311
Rep Power: 3 Fall Back Son is on a distinguished road
Re: Masm32 adding two floats

Actually I was incorrect in saying that I got it right. He might not notice and still give me extra credit though, depending on how harsh his input testing is. But it shouldn't be that harsh since he said in class that if you gave a 'good faith effort' you would get 100. Apparently a lot of people couldn't even read in the values from the user. For some reason, my code worked as long as the user entered 42 values or less (although the project description said to let them enter up to 100). But if the user entered > 42 values, the code didn't give the right answer anymore. My friend looked at it and tried to fix it (his project worked completely) and couldn't figure out what was different that it didn't work. When he got done changing some shit around, it only accepted up to 40 values while working correctly. This was all tried on my machine - I'm not sure if that matters. I'm going to post the code, I'm hoping someone can try to run it and see if it works for you.... also, maybe someone can spot an error that causes this problem. Its looping through the "correct number of times" in all cases... it just generates the wrong results when you enter more than 40 values.

This post is the full code. Below this post, I'm posting some 'areas of interest' that i think could possibly be causing it. Of course, I don't know that for a fact otherwise I'd have fixed it, so it could be anywhere, really. But I tried some print statements and such to make sure values are what I expected, and they are...so i don't know whats going on.

;

;;;; CONSOLE ASSEM & LINK to compile. 

 include \masm32\include\masm32rt.inc
      
.code

start:

call main
inkey 
exit

main proc
LOCAL myArray[100]:QWORD
LOCAL nrValues:DWORD
LOCAL getValues:DWORD

cls
finit


;; call the functions to get the num of values from user
;; put them in an array, average them, and print them out
call getNrValues
mov [nrValues], eax
mov edi, [nrValues]
call storeUserInput
mov ecx, [nrValues]
call calculateAvg
call displayAvg


ret

main endp

;/*********************************************************** 
; Function name:    getNrValues                    
; ***********************************************************

getNrValues proc
LOCAL myValue:DWORD
LOCAL above:DWORD
LOCAL below:DWORD

;; a loop to force the user to input a number between 10 and 100
outOfRange:

print chr$(10,13)
mov myValue, sval(input("Enter a number between 10 and 100: ")  )
print "You entered "
print str$(myValue)
mov [above],100
mov [below],10
mov edi,[myValue]
cmp edi,[below]
jl outOfRange ;; if the user input a number below 10, ask to reinput
mov edi,[myValue] 
cmp edi,[above]
jg outOfRange ;; if the user input a nr above 100, ask to reinput
print " which is valid input."
print chr$(10,13)
mov eax,[myValue]

ret 
getNrValues endp

;/*********************************************************** 
; * Function name:    storeUserInput                        
; ***********************************************************/

storeUserInput proc
LOCAL myFP:QWORD
LOCAL myArray[100]:QWORD
LOCAL arrayAddr:DWORD
LOCAL myString:DWORD
LOCAL answer1[20]:BYTE

 mov ecx, edi

lea edi, myArray ; edi holds the address of myArray


forloop:
    push ecx

mov eax,input("Enter a floating pt. number then hit enter: ") ; gets the String 
mov ebx, eax
push edi
invoke StrToFloat,ebx,ADDR myFP ; converts the String to a float and puts it in myFP
pop edi

    lea ebx, myFP ;; ebx holds the addr of the FP
    mov eax, [ebx] ;; eax holds the value of the FP
    mov [edi], eax ;; the array holds the value of the FP
    add ebx, 4 ;; 
    mov eax, [ebx] ;; eax holds the second part of the FP
    mov [edi+4], eax ;; the value at addr + 4 is now the FP
    add edi, 8
    pop ecx
    loop forloop

lea edi, myArray
mov eax, ecx

ret
storeUserInput endp

;/*********************************************************** 
; * Function name:    calculateAvg                          *
; ***********************************************************/

calculateAvg proc
LOCAL arrayAddr:DWORD
LOCAL myFP1:QWORD
LOCAL counter:DWORD
LOCAL answer1[20]:BYTE
LOCAL total:DWORD
LOCAL nrValues:DWORD
mov [nrValues], ecx

push ecx
mov [total], 0
print chr$(13,10)
fldz
mov esi, edi
pop ecx
aLoop:
    push ecx
    ;; get the value the user entered
    lea ebx, myFP1 
    mov eax, [esi]
    mov [ebx], eax
    add ebx, 4
    mov eax, [esi+4]
    mov [ebx], eax
    fld myFP1
    fadd
    add esi, 8
    
    ;; convert the value to a string then print it out
    push esi
    invoke FloatToStr,myFP1,ADDR answer1
    print "The value you entered was "
    invoke  StdOut,ADDR answer1; print as float
    print chr$(10,13)
    pop esi
    pop ecx
    
    loop aLoop
 
fidiv [nrValues] ;; get the average of the floats the user entered
ret
calculateAvg endp

;/*********************************************************** 
; * Function name:    displayAvg                                               
; ***********************************************************/

displayAvg proc
LOCAL myFP1:QWORD
LOCAL answer1[20]:BYTE

;; print out the average of the floats the user entered
fstp [myFP1] 
print chr$(13,10,13,10)
print "The average of the values you entered is "
invoke FloatToStr,myFP1,ADDR answer1
invoke StdOut,ADDR answer1
print chr$(13,10)

ret
displayAvg endp
end start

Last edited by Fall Back Son; Mar 31st, 2008 at 7:48 PM.
Fall Back Son is offline   Reply With Quote