Approximating Pi Using x86-64:
;;;
;;; group3.s
;;; Compute Pi
;;;
;;; Note: I am still working of getting the limit part of this
;;; program correct.
;;;
section .data
zero: dq 0.0
one: dq 1.0
two: dq 2.0
four: dq 4.0
negone: dq -1.0
limit: dq 0.000001
;;; Test
SYS_WRITE: equ 1
SYS_READ: equ 0
STDOUT: equ 1
STDIN: equ 0
SYS_EXIT: equ 60
prompt: db "How many digits of precision would you like (0-9)? "
prompt_len: equ $-prompt
buffer: db 1
format db "%f", 10, 0
section .text
extern printf
global main
main:
push rbp
mov rbp, rsp
;; Compute pi
movsd xmm0, qword [limit]
call compute_pi
; Return value in xmm0
;; Print result
mov rdi, format
mov al, 1
call printf
mov rax, 0
pop rbp
ret
compute_pi:
push rbp
mov rbp, rsp
; xmm0 = Approximation limit
; Return result in xmm0
; YOUR CODE HERE
mov rax, SYS_WRITE ; Prompt
mov rdi, STDOUT
mov rsi, prompt
mov rdx, prompt_len
Syscall
mov rax, SYS_READ ; Receiving input
mov rdi, STDIN
mov rsi, buffer
mov rdx, buffer
Syscall
mov r15, [buffer]
sub r15, 0x000000000a660a30
; Initializing registers
movsd xmm1, qword[one] ; xmm1 = 1
movsd xmm2, qword[two] ; xmm2 = 2
movsd xmm4, qword[four] ; xmm4 = 4
movsd xmm5, qword[zero] ; xmm5 = 0
movsd xmm6, qword[negone] ; xmm6 = -1
movsd xmm3, qword[four]
addsd xmm3, xmm6 ; xmm3 = 3
movsd xmm0, xmm3 ; starts off with a three
movsd xmm11, xmm6 ; Needs to be negative initially
movsd xmm15, xmm4
mulsd xmm15, xmm4
mulsd xmm15, xmm4
mulsd xmm15, xmm4
mulsd xmm15, xmm4
mulsd xmm15, xmm4 ; xmm15 now contains 1024
; Begin loop
loop1:
; Setting up the i part
movsd xmm8, xmm5
movsd xmm9, xmm5
movsd xmm10, xmm5
; Setting up the 2i part
mulsd xmm8, xmm2
mulsd xmm9, xmm2
mulsd xmm10, xmm2
; Incrementing appropriately
addsd xmm8, xmm2
addsd xmm9, xmm3
addsd xmm10, xmm4
; Getting the product into xmm8
mulsd xmm8, xmm9
mulsd xmm8, xmm10
; Performing division
movsd xmm14, xmm4
divsd xmm14, xmm8
; Doing the negative part
mulsd xmm11, xmm6
mulsd xmm14, xmm11
; Add to total
addsd xmm0, xmm14
; increment i
addsd xmm5, xmm1
ucomisd xmm5, xmm15
jne loop1
xor rax, rax
xor r14, r14
mov rax, 0x00000a66302e3025 ;0
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6631302e3025 ;1
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6632302e3025 ;2
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6633302e3025 ;3
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6634302e3025 ;4
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6635302e3025 ;5
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6636302e3025 ;6
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6637302e3025 ;7
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6638302e3025 ;8
mov [format], rax
cmp r14, r15
je .done
inc r14
mov rax, 0x000a6639302e3025 ;9
mov [format], rax
cmp r14, r15
je .done
inc r14
;;; Unfortunately, I have run out of time, and was not able to get
;;; this working past 9 digits of precision.
.done:
pop rbp
ret