added the asm, even though after 4 hours of debugging it still didn't worked ( and using ai to debug ) this was an interesting add-on
This commit is contained in:
@@ -1,7 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
USE_ASM=0
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [--asm] <number>"
|
||||
echo
|
||||
echo " <number> nombre de termes à afficher"
|
||||
echo " --asm utilise le programme assembleur ./fib"
|
||||
echo
|
||||
echo "sans --asm, le calcul est fait directement en bash"
|
||||
}
|
||||
|
||||
if [[ $# -lt 1 || $# -gt 2 ]]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--asm" ]]; then
|
||||
USE_ASM=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "usage: $0 <number>"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -12,41 +36,62 @@ fi
|
||||
|
||||
n=$1
|
||||
|
||||
declare -A memo
|
||||
memo[1]=0
|
||||
memo[2]=1
|
||||
|
||||
result=0
|
||||
|
||||
fib() {
|
||||
fib_bash() {
|
||||
local k=$1
|
||||
local a
|
||||
local b
|
||||
local a=0
|
||||
local b=1
|
||||
local tmp
|
||||
|
||||
if [[ -n "${memo[$k]:-}" ]]; then
|
||||
result=${memo[$k]}
|
||||
return
|
||||
for ((j = 0; j < k; j++)); do
|
||||
tmp=$((a + b))
|
||||
a=$b
|
||||
b=$tmp
|
||||
done
|
||||
|
||||
printf '%s\n' "$a"
|
||||
}
|
||||
|
||||
fib_asm() {
|
||||
local k=$1
|
||||
local bin="$DIR/fib"
|
||||
|
||||
if [[ ! -x "$bin" ]]; then
|
||||
echo "error: ASM binary not found or not executable: $bin" >&2
|
||||
echo "compile with:" >&2
|
||||
echo " nasm -f elf64 fib.asm -o fib.o && ld fib.o -o fib" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fib $((k - 1))
|
||||
a=$result
|
||||
"$bin" "$k"
|
||||
}
|
||||
|
||||
fib $((k - 2))
|
||||
b=$result
|
||||
display_value() {
|
||||
local value=$1
|
||||
local last=$2
|
||||
|
||||
memo[$k]=$((a + b))
|
||||
result=${memo[$k]}
|
||||
if command -v cowsay >/dev/null 2>&1; then
|
||||
if ((last)); then
|
||||
printf '%s\n' "$value" | cowsay -e oo -T U
|
||||
else
|
||||
printf '%s\n' "$value" | cowsay
|
||||
fi
|
||||
else
|
||||
printf '%s\n' "$value"
|
||||
fi
|
||||
}
|
||||
|
||||
for ((i = 1; i <= n; i++)); do
|
||||
fib "$i"
|
||||
value=$result
|
||||
if ((USE_ASM)); then
|
||||
value="$(fib_asm "$i")"
|
||||
else
|
||||
value="$(fib_bash "$i")"
|
||||
fi
|
||||
|
||||
if ((i < n)); then
|
||||
printf '%s\n' "$value" | cowsay # il y a eu un peu de problèmes pour afficher correctement le nombre avec cowsay il attendait une sorte d'input ??
|
||||
display_value "$value" 0
|
||||
sleep 1
|
||||
clear
|
||||
else
|
||||
printf '%s\n' "$value" | cowsay -e oo -T U
|
||||
display_value "$value" 1
|
||||
fi
|
||||
done
|
||||
|
||||
104
src/bash_scripts/fib.asm
Normal file
104
src/bash_scripts/fib.asm
Normal file
@@ -0,0 +1,104 @@
|
||||
; x86-64 Linux, NASM
|
||||
; usage: ./fib 10
|
||||
; output: 55
|
||||
|
||||
global _start
|
||||
|
||||
section .bss
|
||||
buffer resb 32
|
||||
|
||||
section .text
|
||||
|
||||
_start:
|
||||
mov rdi, [rsp] ; argc
|
||||
cmp rdi, 2
|
||||
jl error
|
||||
|
||||
mov rsi, [rsp + 16] ; argv[1]
|
||||
call atoi ; rax = n
|
||||
|
||||
mov rcx, rax
|
||||
|
||||
xor rax, rax ; a = 0
|
||||
mov rbx, 1 ; b = 1
|
||||
|
||||
test rcx, rcx
|
||||
jz print_result
|
||||
|
||||
fib_loop:
|
||||
mov rdx, rax
|
||||
add rdx, rbx
|
||||
mov rax, rbx
|
||||
mov rbx, rdx
|
||||
dec rcx
|
||||
jnz fib_loop
|
||||
|
||||
print_result:
|
||||
call print_uint
|
||||
call exit_ok
|
||||
|
||||
error:
|
||||
mov rax, 60
|
||||
mov rdi, 1
|
||||
syscall
|
||||
|
||||
exit_ok:
|
||||
mov rax, 60
|
||||
xor rdi, rdi
|
||||
syscall
|
||||
|
||||
atoi:
|
||||
xor rax, rax
|
||||
|
||||
atoi_loop:
|
||||
movzx rdx, byte [rsi]
|
||||
cmp rdx, 0
|
||||
je atoi_done
|
||||
|
||||
cmp rdx, '0'
|
||||
jl atoi_done
|
||||
cmp rdx, '9'
|
||||
jg atoi_done
|
||||
|
||||
sub rdx, '0'
|
||||
imul rax, rax, 10
|
||||
add rax, rdx
|
||||
|
||||
inc rsi
|
||||
jmp atoi_loop
|
||||
|
||||
atoi_done:
|
||||
ret
|
||||
|
||||
print_uint:
|
||||
mov rdi, buffer + 31
|
||||
mov byte [rdi], 10
|
||||
dec rdi
|
||||
|
||||
mov rcx, 10
|
||||
|
||||
test rax, rax
|
||||
jnz convert_loop
|
||||
|
||||
mov byte [rdi], '0'
|
||||
jmp print_now
|
||||
|
||||
convert_loop:
|
||||
xor rdx, rdx
|
||||
div rcx
|
||||
add dl, '0'
|
||||
mov [rdi], dl
|
||||
dec rdi
|
||||
test rax, rax
|
||||
jnz convert_loop
|
||||
|
||||
inc rdi
|
||||
|
||||
print_now:
|
||||
mov rax, 1
|
||||
mov rsi, rdi
|
||||
mov rdx, buffer + 32
|
||||
sub rdx, rsi
|
||||
mov rdi, 1
|
||||
syscall
|
||||
ret
|
||||
Reference in New Issue
Block a user