154 lines
3.0 KiB
NASM
154 lines
3.0 KiB
NASM
; THIS CODE HAS BEEN TESTED AND IS FULLY OPERATIONAL.
|
|
|
|
; Problem Statement: Write 80387 ALP to find the roots of the quadratic equation. All the possible cases must be considered in calculating the roots.
|
|
|
|
; Code from Microprocessor (SPPU - Second Year - Computer Engineering - Content) repository on KSKA Git: https://git.kska.io/sppu-se-comp-content/Microprocessor/
|
|
|
|
|
|
; BEGINNING OF CODE
|
|
section .data
|
|
msg1 db "Complex Root",10
|
|
msglen1 equ $-msg1
|
|
msg2 db "Root 1: "
|
|
msglen2 equ $-msg2
|
|
msg3 db 10, "Root 2: "
|
|
msglen3 equ $-msg3
|
|
a dd 1.00
|
|
b dd -6.00
|
|
c dd 8.00
|
|
four dd 4.00
|
|
two dd 2.00
|
|
|
|
hdec dq 100
|
|
point db "."
|
|
|
|
section .bss
|
|
|
|
root1 resd 1
|
|
root2 resd 1
|
|
resbuff rest 1
|
|
temp resb 2
|
|
disc resd 1
|
|
|
|
%macro write 2 ;macro for display
|
|
mov rax,1
|
|
mov rdi,1
|
|
mov rsi,%1
|
|
mov rdx,%2
|
|
syscall
|
|
%endmacro
|
|
|
|
%macro read 2 ;macro for input
|
|
mov rax,0
|
|
mov rdi,0
|
|
mov rsi,%1
|
|
mov rdx,%2
|
|
syscall
|
|
%endmacro
|
|
|
|
|
|
%macro exit 0 ;macro for exit
|
|
mov rax,60
|
|
xor rdi,rdi
|
|
syscall
|
|
%endmacro
|
|
|
|
section .text
|
|
global _start
|
|
_start:
|
|
|
|
finit ;initialise 80387 co-processor
|
|
fld dword[b] ;stack: b
|
|
|
|
fmul dword[b] ;stack: b*b
|
|
|
|
fld dword[a] ;stack: a, b*b
|
|
|
|
fmul dword[c] ;stack: a*c, b*b
|
|
|
|
fmul dword[four] ;stack: 4*a*c,b*b
|
|
|
|
fsub ;stack: b*b - 4*a*c
|
|
|
|
ftst ;compares ST0 and 0
|
|
jb no_real_solutions
|
|
|
|
fsqrt ;stack: sqrt(b*b - 4*a*c)
|
|
fst dword[disc] ;store disc= sqrt(b*b - 4*a*c)
|
|
|
|
fsub dword[b] ;stack: disc-b
|
|
|
|
fdiv dword[a] ;stack: disc-b/2*a or (-b+disc)/2a
|
|
|
|
|
|
fdiv dword[two]
|
|
|
|
write msg2,msglen2
|
|
|
|
call disp_proc
|
|
|
|
fldz ;stack:0
|
|
fsub dword[disc] ;stack:-disc
|
|
fsub dword[b] ;stack: -disc - b
|
|
fdiv dword[a] ;stack: (-b - disc)/(2*a)
|
|
fdiv dword[two]
|
|
|
|
write msg3,msglen3
|
|
call disp_proc
|
|
jmp exi
|
|
|
|
no_real_solutions:
|
|
write msg1,msglen1
|
|
exi :
|
|
|
|
mov rax,60
|
|
mov rdi,1
|
|
syscall
|
|
|
|
|
|
disp_proc:
|
|
FIMUL dword[hdec]
|
|
FBSTP tword[resbuff]
|
|
mov rsi,resbuff+9
|
|
mov rcx,09
|
|
next1:
|
|
|
|
push rcx
|
|
push rsi
|
|
|
|
mov bl,[rsi]
|
|
call disp
|
|
|
|
pop rsi
|
|
pop rcx
|
|
|
|
dec rsi
|
|
loop next1
|
|
|
|
push rsi
|
|
write point,1
|
|
pop rsi
|
|
mov bl,[rsi]
|
|
call disp
|
|
ret
|
|
|
|
|
|
disp:
|
|
mov rdi,temp ;mov dnum address into edi
|
|
mov rcx,02 ;initialize ecx with 2
|
|
dispup1:
|
|
rol bl,4 ;rotate bl by 4 bits
|
|
mov dl,bl ;move bl into dl
|
|
and dl,0fh ;and of dl with 0fh
|
|
add dl,30h ;add 30h into dl
|
|
cmp dl,39h ;compare dl with 39h
|
|
jbe dispskip1 ;jump if below and equal to dispskip1
|
|
add dl,07h ;add 7h into dl
|
|
dispskip1:
|
|
mov [rdi],dl ;mov dl into dnum
|
|
inc rdi ;increament edi by a byte
|
|
loop dispup1 ;loop dispup1 while ecx not zero
|
|
write temp,2 ;Display dnum by calling macro
|
|
ret ;return from procedure
|
|
; END OF CODE
|