The well-known Leibniz-formula to calculate "pi" with many iterations.
Surely, there are faster ways to calculate pi, and there may be the question WHY to calculate pi, but nevertheless...
We can practice here to deal with floating-point-numbers, and we see, how we can print floating-point-numbers (with help of the printf-routine of C.
; nasm -f elf64 calculatepi1.asm -o calculatepi1.o
; gcc -no-pie -m64 calculatepi1.o -o calculatepi1
; Leibniz says : pi/4 =1/1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 .....
section .data
var_oben dq 1.0 ; Startwert Zaehler
var_unten dq 1.0 ; Startwert Teiler
var_0 dq 0.0 ; Null
var_2 dq 2.0 ; Zwei
var_minus1 dq -1.0 ; minus 1
MSG_RESULT db "pi = %0.18lf", 10, 0
section .text
extern printf
global main
main:
push rbp
mov rbp,rsp
; Set the number of iterations for the Leibniz formula
mov rax, 200000
movsd xmm2, qword [var_0] ; xmm2 beginnt bei null und nimmt dann die Leibnizzahl als Viertel auf.
; Loop to calculate Pi using Leibniz formula
leibniz_loop:
; Calculate next term
movsd xmm0, qword [var_oben]
movsd xmm1, qword [var_unten]
divsd xmm0, xmm1
addsd xmm2, xmm0 ; xmm2 hat das Viertel des Leibnizwertes!
; alternating sign
movsd xmm3, qword[var_minus1]
movsd xmm0, qword [var_oben]
mulsd xmm0, xmm3
movsd qword [var_oben], xmm0
; Teiler zwei dazu...
movsd xmm3, qword [var_unten]
addsd xmm3, qword [var_2]
movsd qword [var_unten], xmm3
; Decrement loop counter
dec rax
jnz leibniz_loop
; Multiply result by 4
movsd xmm3, qword [var_2]
mulsd xmm2, xmm3
mulsd xmm2, xmm3
movsd xmm0, xmm2
mov rdi, MSG_RESULT ; set format for printf
mov rax,1 ; set one xmm registers
call printf ; Call C function
mov rax,0 ; normal, no error, return value
pop rbp
mov rax, 60 ; System call number for sys_exit
xor rdi, rdi ; Exit code 0
syscall
This is far from being optimized for speed or whatever. It is written in a manner to understand easier what is going on.