For this project, I am supposed to calculate the first 94 fibonacci numbers & store them in an array. Then prompt the user to either: 1) display all or part of the array, 2) display the mean or all or part of the array, 3) display all or part of the standard deviation of the array, 4) calculate the square root of a real number, or 5) quit. Three of the five items work, but I'm having issues with the mean and standard deviation procedures. Any help would be greatly appreciated.
TITLE PROG4.asm ;File name of program
MAXSTR equ 256d ;maximum length of input string
LF equ 10d ;line feed character
CR equ 13d ;carrage return character
NL equ LF,CR ;combined line feed and return
DOUBLESPC equ LF,LF,CR ;used to produce double spacing
TRUE equ 1h ;boolean flag
FALSE equ 0h ;boolean flag
INCLUDE io64.inc ;required for I/O routines
INCLUDE fpu_io64.inc ;required for 64-bit FPU instructions
.DATA
Intro BYTE NL, 'This program will calculate the first 94 Fibonacci numbers and store', NL, \
'them in an array. The user will then be able to print or display', NL, \
'the mean or standard deviation of all or any part of the array.',NL, \
'The program will also calculate the square root of a real number.',NL, 0
Menu BYTE NL,NL, ' Fibonacci Fun', NL, NL, \
'1) Display ALL or any PART of the Fibonacci Array', NL, \
'2) Display the "Mean" of ALL or any PART of the Array', NL, \
'3) Display the "Standard Deviation" of ALL or any PART of the Array', NL, \
'4) Calculate the Square Root of a Real number', NL, \
'5) Quit', NL, NL, 0
Prompt1 BYTE NL, 'Type a number to select --> ', 0
Prompt2 BYTE NL, 'Enter the starting array index --> ', 0
Prompt3 BYTE NL, 'Enter the number of elements to process --> ', 0
Prompt4 BYTE NL, 'Enter the number the square root of --> ', 0
Output1 BYTE 'The selected elements are: ', 0
Output2 BYTE 'The Mean for the selected elements is: ', 0
Output3 BYTE 'The Standard Deviation for the selected elements is: ', 0
Output4 BYTE NL,NL, 'The Square Root of the number is: ', 0
Error1 BYTE 'Cannot compute mean and standard deviation with less than two elements!', 0
Error2 BYTE NL, 'You cannot take the square root of negative number!',NL, NL, 0
Error3 BYTE NL, 'That is not a valid menu selection. Try again.', 0
Error4 BYTE 'That is not a valid array index.', NL, \
'Seleect 0 through 93.', 0
Error5 BYTE 'That is not a valid number of elements. Try again.', 0
Error6 BYTE 'That is not a valid number for a square root. Try again.', 0
newLine BYTE NL, 0
InString BYTE MAXSTR dup(0)
OutString BYTE MAXSTR dup(0)
MaxIntStr BYTE NL,LF,'Max Int for 64 bits is -> ',0
MaxInt QWORD 0FFFFffffFFFFffffh ;18446744073709551615d
InKey BYTE 0
BoolFlag BYTE FALSE
UsrSelect BYTE 0
StartIndex BYTE 0
StIdx QWORD 0
NumElement BYTE 0
NumElmt QWORD 0
UsrNumSR QWORD 0
UsrSqRt REAL8 0.0
TestInMean BYTE 0
TestMean REAL8 0.0
Tempo REAL8 0.0
MeanSum REAL8 0.0
Test2 BYTE 0
Test3 QWORD 0
Test4 BYTE 0
FibArray QWORD 94 DUP(?)
TestArray QWORD 1, 2, 3, 4, 5 DUP(?)
.CODE
main PROC
sub rsp, 28h ;reserve stack space for five (5) qwords
lea rsi,Intro ;point to the Intro string
call PrintStr ; and print it
call calculateFibonacci ;call calculateFibonacci procedure
call DisplayMenu ;display the menu
add rsp, 28h ;restore stack space
call ExitProcess ;exit to operating system
main ENDP
;--------------------- Procedure to display Menu ---------------------------------
; Requires : Nothing
; Process : Displays Menu & calls appropriate protocols
; : All volitile registers are preserved.
; Return : Nothing
;---------------------------------------------------------------------------------
DisplayMenu PROC USES rax rcx rdx r8 r9 r10 r11
sub rsp, 28h ;save volitile registers
call clearRegs
@@Start:lea rsi, Menu ;point to Menu
call PrintStr ;print the string
@@Input:lea rsi, Prompt1 ;point to Prompt1
call PrintStr ;print the string
lea rsi, UsrSelect ;point to UsrSelect
call GetChar ;get the character
cmp UsrSelect, 31h ;compare UsrSelect with 31h
jb @@Err ; if below, jump to @@Err
je @@User1 ; if even, @@User1
cmp UsrSelect, 32h ;compare UsrSelect, 32h
je @@User2 ; if even, @@User2
cmp UsrSelect, 33h ;compare UsrSelect, 33h
je @@User3 ; if even, @@User3
cmp UsrSelect, 34h ;compare UsrSelect, 34h
je @@User4 ; if even, @@User4
cmp UsrSelect, 35h ;compare UsrSelect, 35h
je @@Done ; if even, @@Done
jmp @@Err ;jump to @@Err
@@User1:call printFibonacci ;call printFibonacci procedure
jmp @@Start ;jump to @@Start
@@User2:call calculateMean ;call calculateMean procedure
jmp @@Start ;jump to @@Start
@@User3:call standardDeviation ;call standardDeviation procedure
jmp @@Start ;jump to @@Start
@@User4:call squareRoot ;call squareRoot procedure
jmp @@Start ;jump to @@Start
@@Err: lea rsi, Error3 ;point to Error3
call PrintStr ;print the string
jmp @@Input ;jump to @@Input
@@Done: add rsp, 28h ;restore volitile registers
ret ;return to calling procedure
DisplayMenu ENDP
;----------------- Procedure to calculate the Fibonacci sequence -----------------
; Requires : Nothing
; Process : Calculates the first 94 Fibonacci numbers. Stored in an array.
; : All volitile registers are preserved.
; Return : Nothing
;---------------------------------------------------------------------------------
;*********************************************************************************************
;CALCULATE FIBONACCI SEQUENCE TESTED AND WORKING
;*********************************************************************************************
calculateFibonacci PROC USES rax rbx rcx rdx r8 r9 r10 r11
sub rsp, 28h ;save contents of volitile registers
lea rcx, FibArray ;get address of first array element
mov rsi, rcx ;copy rcx to rsi
mov rdx, 92d ;copy 92d into rdx (counter)
mov rcx, rdx ;copy contents of rdx into rcx
mov rbx, 0d ;copy 0d into rbx
mov [rsi], rbx ;copy 0d into array element 0
mov r10, 0d ;copy 0d into r10 register
add rsi, 8 ;get address of next array element
mov rbx, 1d ;copy 1d into rbx
mov [rsi], rbx ;copy contents of rbx into array element
mov r11, 1d ;copy 1d into r11 register
@@Start:add rsi, 8 ;get address of next array element
add r10, r11 ;add r10 and r11 register, new value in r10
mov [rsi], r10 ;copy new value into next array element
sub rsi, 8 ;get address of previous array element
mov r11, [rsi] ;copy value in previous array element to r11
add rsi, 8 ;get address of next array element
loop @@Start ;loop to start until rcx == 0
@@Done: add rsp, 28h ;restore volitile registers
ret ;return to calling procedure
calculateFibonacci ENDP
;------------------- Procedure to clear all registers ----------------------------
; Requires : Nothing
; Process : Clears all registers via the xor command
; : All volitile registers are preserved.
; Return : Nothing
;---------------------------------------------------------------------------------
clearRegs PROC USES rax rbx rcx rdx r8 r9 r10 r11
sub rsp, 28h
xor rax, rax
xor rbx, rbx
xor rcx, rcx
xor rdx, rdx
xor r8, r8
xor r9, r9
xor r10, r10
xor r11, r11
xor rsi, rsi
xor rdi, rdi
add rsp, 28h
ret
clearRegs ENDP
;------------------- Procedure to Print the Fibonacci sequence -------------------
; Requires : Nothing
; Process : Prints the first 94 Fibonacci numbers. Stored in an array.
; : All volitile registers are preserved.
; Return : Nothing
;---------------------------------------------------------------------------------
;*******************************************************************************************
;PRINT FIBONACCI SEQUENCE WORKS 1st RUN THROUGH, BREAKS ON ZERO ELEMENT AFTER THAT
;*******************************************************************************************
printFibonacci PROC USES rax rbx rcx rdx r8 r9 r10 r11
sub rsp, 28h ;save contents of volitile registers
@@Pro1: lea rsi, Prompt2 ;Prompt user for starting index
call PrintStr ;print the string
lea rsi, StartIndex ;point to StartIndex
call ReadStr ;ReadString
lea rsi, StartIndex ;point to StartIndex
lea rdi, StIdx ;point to StIdx
call Ascii2Qword ;convert from Ascii to Qword
cmp StIdx, 0d ;compare StartIndex with '0'
jb @@Err1 ; if below, jump to @@Err1
@@Pro2: lea rsi, Prompt3 ;Prompt the user for number of elements to process
call PrintStr ;print the string
lea rsi, NumElement ;storage location for number of elements
call ReadStr ;read string of user input
lea rsi, NumElement ;point to NumElement
lea rdi, NumElmt ;point to NumElmt
call Ascii2Qword ;convert from Ascii2Qword
cmp NumElmt, 1d ;compare NumElement with '1'
jb @@Err2 ; if below, jump to @@Err2
mov rdx, OFFSET FibArray ;copy OFFSET FibArray to rdx
mov rcx, StIdx ;copy StIdx to rcx
cmp StIdx, 0d ;comare rcx to 0d
je @@Skip ; if even, jump to @@Skip
@@SIdx: add rdx, 8 ;get address of next array element
loop @@SIdx ;loop to @@SIdx
@@Skip: mov rcx, NumElmt ;copy NumElmt to rcx
@@Start:lea rsi, [rdx] ;point to next element in array
lea rdi, Test2 ;point to Test2
call Qword2Ascii ;convert Qword 2 Ascii character
lea rsi, Test2 ;point to Test2
call PrintStr ;print the string
add rdx, 8 ;get address of next array element
lea rsi, newLine ;point to newLine
call PrintStr ;print the string
loop @@Start ;loop to @@Start
jmp @@Done ;jump to @@Done
@@Err1: lea rsi, Error4 ;point to Error4
call PrintStr ;print the string
jmp @@Pro1 ;jump to @@Pro1
@@Err2: lea rsi, Error5 ;point to Error5
call PrintStr ;print the string
jmp @@Pro2 ;jump to @@Pro2
@@Done: add rsp, 28h ;restore volitile registers
ret ;return to calling procedure
printFibonacci ENDP
;---------------------- Procedure to Calculate Square Root -----------------------
; Requires : Nothing
; Process : Calculates the Square Root of a Number
; : All volitile registers are preserved.
; Return : Nothing
;---------------------------------------------------------------------------------
;***********************************************************************************
;SQUARE ROOT PROCEDURE TESTED AND FULLY FUNCTIONING
;***********************************************************************************
squareRoot PROC USES rax rbx rcx rdx r8 r9 r10 r11
sub rsp, 28h ;restore volitile registers
call clearRegs ;call procedure to clear all registers
@@Start:lea rsi, Prompt4 ;point to Prompt4
call PrintStr ;print the string
lea rsi, UsrNumSR ;point to UsrNumSR
call ReadStr ;read the string frme user input
lea rsi, UsrNumSR ;point to UsrNumSR
lea rdi, UsrSqRt ;point to UsrSqRt
call Ascii2Real ;convert Ascii to FPU digit
cmp UsrSqRt, 30h ;compare UsrSqRt with 30h
jbe @@Error ; if below or even, jump to @@Error
finit ;initialize fpu
fld UsrSqRt ;push real value onto top of stack
fsqrt ;replace value on top of stack with its sqare root
fstp UsrSqRt ;pop top of stack off into UsrSqRt
lea rsi, UsrSqrt ;point to UsrSqRt
lea rdi, UsrNumSR ;point to UsrNumSR
call Real2Ascii ;convert Real to Ascii
lea rsi, Output4 ;point to Output4
call PrintStr ;print the string
lea rsi, UsrNumSR ;point to UsrNumSR
call PrintStr ;print the string
jmp @@Done ;jump to @@Done
@@Error:lea esi, Error2 ;point to Error2
call PrintStr ;print the string
jmp @@Start ;jump to @@Start
@@Done: add rsp, 28h ;restore volitile registers
ret ;return to calling procedure
squareRoot ENDP
;---------------------- Procedure to Calculate Mean ======-----------------------
; Requires : Nothing
; Process : Calculates the Mean of a range of numbers
; : All volitile registers are preserved.
; Return : Nothing
;---------------------------------------------------------------------------------
;*******************************************************************************************
;CALCULATE MEAN PROCEDURE UNTESTED AND STILL NEEDS MODIFICATION
;*******************************************************************************************
calculateMean PROC USES rax rbx rcx rdx r8 r9 r10 r11
sub rsp, 28h ;reserve stack space
call clearRegs ;call procedure to clear all registers
finit
@@Pro1: lea rsi, Prompt2 ;Prompt user for starting index
call PrintStr ;print the string
lea rsi, StartIndex ;point to StartIndex
call ReadStr ;ReadString
lea rsi, StartIndex ;point to StartIndex
lea rdi, StIdx ;point to StIdx
call Ascii2Qword ;convert from Ascii to Qword
cmp StIdx, 0d
jb @@Err1
@@Pro2: lea rsi, Prompt3 ;Prompt the user for number of elements to process
call PrintStr ;print the string
lea rsi, NumElement ;storage location for number of elements
call ReadStr ;read string of user input
lea rsi, NumElement ;point to NumElement
lea rdi, NumElmt ;point to NumElmt
call Ascii2Qword ;convert from Ascii2Qword
cmp NumElmt, 2d
jb @@Err2
mov rdx, OFFSET FibArray ;copy OFFSET FibArray to rdx
mov rcx, StIdx ;copy StIdx to rcx
cmp StIdx, 0d
je @@Skip
mov rax, 0d
@@SIdx: add rdx, 8 ;get address of next array element
loop @@SIdx ;loop to @@SIdx
@@Skip: mov rcx, NumElmt ;copy NumElmt to rcx
@@Start:add rax, [rdx]
add rdx, 8
loop @@Start
mov Test3, rax
lea rsi, Test3
lea rdi, Test4
call Qword2Ascii
lea rsi, Test4
lea rdi, Tempo
call Ascii2Real
xor rbx, rbx
mov rbx, NumElmt
;mov MeanSum, rax
fld Tempo
fld NumElmt
fdiv
fstp TestMean
lea rsi, TestMean
lea rdi, TestInMean
call Real2Ascii
lea rsi, TestInMean
call PrintStr
jmp @@Done
@@Err1: lea rsi, Error4
call PrintStr
jmp @@Pro1
@@Err2: lea rsi, Error5
call PrintStr
jmp @@Pro2
@@Done: add rsp, 28h
ret
calculateMean ENDP
;-------------------- Procedure to Calculate Std Deviation -----------------------
; Requires : Nothing
; Process : Calculates the Standard Deviation of a range of numbers.
; : All volitile registers are preserved.
; Return : Nothing
;---------------------------------------------------------------------------------
;******************************************************************************************
;WTF????
;******************************************************************************************
standardDeviation PROC USES rax rbx rcx rdx r8 r9 r10 r11
sub rsp, 28h
call clearRegs
@@Start:lea rsi, Prompt2
call PrintStr
lea rsi, StartIndex
call ReadStr
cmp StartIndex, 0d
jb @@Err1
lea rsi, Prompt3
call PrintStr
lea rsi, NumElement
call ReadStr
lea rsi, NumElement
lea rdi, NumElement
cmp NumElement, 1d
jb @@Err2
mov rax, 30h
;mov rcx, StartIndex
@@Loop:
;calculate the mean (average) of all the values in the list
;begin at StartIndex
;go NumElement number of elements
;sum them up
;divid
;by NumElement
;for each number in the list, calculate (value - mean)^2
;begin at StartIndex
;value at start index - mean
;square value
;go through list until last number has been calculated
;calculate the variance by taking the average of all those squared values
;take value and divide by NumElement
;to obtain the standard deviation, take the square root of the variance
;take value and square root
;print the new resulting value
;this value is the std. deviation
@@Err1: lea rsi, Error4
call PrintStr
jmp @@Start
@@Err2: lea rsi, Error5
call PrintStr
jmp @@Start
@@Done: add rsp, 28h
ret
standardDeviation ENDP
END ;End of the code segment
for calcuating the sqare root:
; rax = value = __int64
cvtsi2sd xmm0,rax
sqrtsd xmm0,xmm0
cvttsd2si rax,xmm0
; rax = (__int64) sqrt((double) value)