123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- ;;; Required packages: nasm, gcc
- ;;; compile commands:
- ;;; nasm -f elf 07-square-eq.asm -o bin/07-square-eq.o
- ;;; gcc -m32 -o bin/07-square-eq.out bin/07-square-eq.o
- %define SYSCALL_EXIT 1 ; system call sys_exit
- %define FLOAT32_SIZE_BYTES 4 ; 4 bytes per float32
- section .data
- scan_fmt db "%f", 0x0
- x1_fmt db "x1 = %f", 0xa, 0x0
- x2_fmt db "x2 = %f", 0xa, 0x0
- x_fmt db "x = %f", 0xa, 0x0
- message_enter_abc db "Please enter coefficients a, b, c of equation ax^2 + bx + c = 0", 0xa, 0x0
- result_no_roots db "No roots.", 0xa, 0x0
- result_infinite_roots db "Infinite roots", 0xa, 0x0
- enter_a_fmt db "a = ", 0x0
- enter_b_fmt db "b = ", 0x0
- enter_c_fmt db "c = ", 0x0
- section .bss
- a resb FLOAT32_SIZE_BYTES
- b resb FLOAT32_SIZE_BYTES
- c resb FLOAT32_SIZE_BYTES
- d resb FLOAT32_SIZE_BYTES
- x1 resb FLOAT32_SIZE_BYTES
- x2 resb FLOAT32_SIZE_BYTES
- section .text
- extern printf
- extern scanf
- global main
- main:
- push message_enter_abc
- call printf
- add esp, 4
- ; printf (enter_a_fmt)
- push enter_a_fmt
- call printf
- add esp, 4
- ; scanf (scan_fmt, a)
- push a
- push scan_fmt
- call scanf
- add esp, 8
- ; printf (enter_b_fmt)
- push enter_b_fmt
- call printf
- add esp, 4
- ; scanf (scan_fmt, &b)
- push b
- push scan_fmt
- call scanf
- add esp, 8
- ; printf (enter_c_fmt)
- push enter_c_fmt
- call printf
- add esp, 4
- ; scanf (scan_fmt, &c)
- push c
- push scan_fmt
- call scanf
- add esp, 8
- cmp DWORD [a], __float32__(0.0)
- je .aIsZero
- jmp .calcD
- .aIsZero:
- cmp DWORD [b], __float32__(0.0)
- je .abAreZero
- push DWORD __float32__(-1.0) ; push -1.0 in evaluation stack
- ; take value -1.0 from evaluation stack
- fld DWORD [esp] ; stack: [-1]
- add esp, 4 ; shift evaluation stack into initial point
- fld DWORD [c] ; stack: [-1, c]
- fmul ; stack: [-c]
- fld DWORD [b] ; stack: [-c, b]
- fdiv ; stack: [-c / b]
- fstp DWORD [x1] ; stack: [], result written into x1
-
- sub esp, 8 ; reserve stack for a float64 (%f requires float64 in printf)
- mov ebx, x1
- fld DWORD [ebx] ; load float32 in current stack place (32 bits)
- fstp QWORD [esp] ; store float64 (8087 does the conversion from float32 internally)
- push x_fmt
- call printf
- add esp, 12
- jmp .done
- .abAreZero:
- cmp DWORD [c], __float32__(0.0)
- je .abcAreZero
- jmp .noRoots
- .abcAreZero:
- push result_infinite_roots
- call printf
- add esp, 4
- jmp .done
- .calcD:
- fld DWORD [b] ; stack: [b]
- fld DWORD [b] ; stack: [b, b]
- fmul ; stack: [b * b]
- fld DWORD [a] ; stack: [b * b, a]
- fld DWORD [c] ; stack: [b * b, a, c]
- fmul ; stack: [b * b, a * c]
- push DWORD __float32__(4.0) ; push 4.0 in evaluation stack
- ; take value 4.0 from evaluation stack
- fld DWORD [esp] ; stack: [b * b, a * c, 4]
- add esp, 4 ; shift evaluation stack into initial point
- fmul ; stack: [b * b, 4 * a * c]
- fsub ; stack: [b * b - 4 * a * c]
- fstp DWORD [d] ; stack: [], result written into d
- push DWORD __float32__(0.0) ; push 0.0 in evaluation stack
- ; take value 0.0 from evaluation stack
- fld DWORD [esp] ; stack: [b * b, a * c, 4]
- add esp, 4 ; shift evaluation stack into initial point
- fld DWORD [d]
- fcom
- mov eax, DWORD 0
- fstsw ax
- cmp eax, DWORD 0x3100 ; eax = 0x3100 -> less
- je .noRoots
- jmp .calcRoots
- .calcRoots:
- ; calculate x1
- push DWORD __float32__(2.0) ; push -1.0 in evaluation stack
- ; take value 2.0 from evaluation stack
- fld DWORD [esp] ; stack: [2]
- add esp, 4 ; shift evaluation stack into initial point
- fld DWORD [a] ; stack: [2, a]
- fmul ; stack: [2 * a]
- push DWORD __float32__(-1.0) ; push -1.0 in evaluation stack
- ; take value -1.0 from evaluation stack
- fld DWORD [esp] ; stack: [2 * a, -1]
- add esp, 4 ; shift evaluation stack into initial point
- fld DWORD [b] ; stack: [2 * a, -1, b]
- fmul ; stack: [2 * a, -b]
- fld DWORD [d] ; stack: [2 * a, -b, d]
- fsqrt ; stack: [2 * a, -b, sqrt(d)]
- fadd ; stack: [2 * a, -b + sqrt(d)]
- fld
- fdiv ; stack: [(-b + sqrt(d)) / (2 * a)]
- fstp DWORD [x1] ; stack: [], result written into x1
- ; calculate x2
- push DWORD __float32__(2.0) ; push -1.0 in evaluation stack
- ; take value 2.0 from evaluation stack
- fld DWORD [esp] ; stack: [2]
- add esp, 4 ; shift evaluation stack into initial point
- fld DWORD [a] ; stack: [2, a]
- fmul ; stack: [2 * a]
- push DWORD __float32__(-1.0) ; push -1.0 in evaluation stack
- ; take value -1.0 from evaluation stack
- fld DWORD [esp] ; stack: [2 * a, -1]
- add esp, 4 ; shift evaluation stack into initial point
- fld DWORD [b] ; stack: [2 * a, -1, b]
- fmul ; stack: [2 * a, -b]
- fld DWORD [d] ; stack: [2 * a, -b, d]
- fsqrt ; stack: [2 * a, -b, sqrt(d)]
- fsub ; stack: [2 * a, -b - sqrt(d)]
- fld
- fdiv ; stack: [(-b - sqrt(d)) / (2 * a)]
- fstp DWORD [x2] ; stack: [], result written into x2
- ; print result
- sub esp, 8 ; reserve stack for a float64 (%f requires float64 in printf)
- mov ebx, x1
- fld DWORD [ebx] ; load float32 in current stack place (32 bits)
- fstp QWORD [esp] ; store float64 (8087 does the conversion from float32 internally)
- push x1_fmt
- call printf
- add esp, 12
-
- sub esp, 8 ; reserve stack for a float64 (%f requires float64 in printf)
- mov ebx, x2
- fld DWORD [ebx] ; load float32 in current stack place (32 bits)
- fstp QWORD [esp] ; store float64 (8087 does the conversion from float32 internally)
- push x2_fmt
- call printf
- add esp, 12
- jmp .done
- .noRoots:
- push result_no_roots
- call printf
- add esp, 4
- jmp .done
- .done:
- mov eax, SYSCALL_EXIT
- mov ebx, 0
- int 0x80
|