Q: Write an ALP to find out the mean, variance and standard deviation for a given set of numbers.
Floating point instruction seem to be pretty hard to grasp, especially if you are using them for the first time. While coding a solution to this problem, often I found myself opening the Intel ia64 manual confused about the end result of an instruction. Thus I decided to comment the code in detail ,so that readers don't find themselves in a similar situation.
In case you need to refer to the manual here's the link:-
instruction-set-reference-manual
OS:-Linux-64 bit(Ubuntu 14.04 LTS)
r00t@comp:~$ nasm -f elf64 as7.asm
r00t@comp:~$ ld -o as7 as7.o
r00t@comp:~$ ./as7
The mean is 0000000000000017.3333
The variance is 0000000000000134.2222
The standard deviance is 0000000000000011.5854

In case you need to refer to the manual here's the link:-
instruction-set-reference-manual
Code:
Assembler:- NASMOS:-Linux-64 bit(Ubuntu 14.04 LTS)
;Author:-Abhishek Munagekar@Programing Wonders ;blog:- www.prgwonders.blogspot.in ;fb :-www.facebook.com/prgwonders ;Title :-Floating Point Operations ;+++++++++++++++++++++++++++++++++++++ %macro print 2 mov rax,01 mov rdi,0 mov rsi,%1 mov rdx,%2 syscall %endmacro %macro read 2 mov rax,0 mov rdi,1 mov rsi,%1 mov rdx,%2 syscall %endmacro ;++++++++++++++++++++++++++++++++++++++ section .data msg1 : db 10,"The mean is ", len1 :equ $-msg1 msg2: db 10,"The variance is ", len2 :equ $-msg2 msg3: db 10,"The standard deviance is ", len3: equ $-msg3 data: dd 2.0,20.0,30.0 dcpt: db "." precision dw 10000 ;used for making the precision 4 points after decimal section .bss count2 resw 1 ;additional counter count resw 1 ;counter h2acount resb 1 bcd rest 1 ;to store bcd obtained for the printing of results mean resd 1 ;required for calculating the variance dbuff resw 1 ;used for storing byte in ascii section .text global _start: _start: finit ;initialize the math-coprocessor fldz ;push 0.0 onto fpu stack mov r8,data ;set r8 to point the begining of the data array mov r9,0 mov word[count],3h ;initialize the counter addloop: fadd dword[r8] add r8,4 dec word[count] jnz addloop mov word[count],3 ;the sum is now at stack 0 fidiv word[count] fst dword[mean] ;mean is now obtained and stored print msg1,len1 call s0printer ;mean is now printed proceding for variance ;load st0 with 0.0 mov r8,data mov word[count2],3 fldz ;stack initialization remove this line and see fldz ;what happens spent hours debugging this varloop: fldz ;cumulative answer at st1 fld dword[r8] ;cumulative answer at st2 fsub dword[mean] ;st0=x-mean,st1=0;st2=cumulative answer here fst st1 ;st1=st0 fmulp st1,st0 ;st0=(x-mean)^2,st1=cumulative answer fadd ;st0=cumulative answer add r8,4 dec word[count2] jnz varloop mov word[count2],3 fidiv word[count2] fst st1 ;storing variance value here for std deviation print msg2,len2 call s0printer fsqrt ;using the earliear stored value print msg3,len3 call s0printer exiter: mov rax,60 mov rdi,0h syscall s0printer: fimul word[precision] fbstp tword[bcd] ;store bcd integer and pop mov word[count],8h mov r8,bcd add r8,9 ;go to last byte of answer printloop: mov al,byte[r8] call h2a print dbuff,2 dec r8 dec word[count] jnz printloop print dcpt,1 ;print the decimal point now mov byte[count],2 printloop2: mov al,byte[r8] call h2a print dbuff,2 dec r8 dec word[count] jnz printloop2 ret h2a: ;hex to ascii,value at al, output at display buff mov r11,dbuff ;used to point at the base of dbuff mov byte[h2acount],2 mov bl,0h h2aloop: rol al,4 mov bl,al and bl,0Fh cmp bl,9h jbe nocorrection add bl,7h nocorrection: add bl,30h mov byte[r11],bl inc r11 dec byte[h2acount] jnz h2aloop ret
Output
r00t@comp:~$ nasm -f elf64 as7.asm
r00t@comp:~$ ld -o as7 as7.o
r00t@comp:~$ ./as7
The mean is 0000000000000017.3333
The variance is 0000000000000134.2222
The standard deviance is 0000000000000011.5854
No comments:
Post a Comment