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
|
#!/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
|
if [[ $# -ne 1 ]]; then
|
||||||
echo "usage: $0 <number>"
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -12,41 +36,62 @@ fi
|
|||||||
|
|
||||||
n=$1
|
n=$1
|
||||||
|
|
||||||
declare -A memo
|
fib_bash() {
|
||||||
memo[1]=0
|
|
||||||
memo[2]=1
|
|
||||||
|
|
||||||
result=0
|
|
||||||
|
|
||||||
fib() {
|
|
||||||
local k=$1
|
local k=$1
|
||||||
local a
|
local a=0
|
||||||
local b
|
local b=1
|
||||||
|
local tmp
|
||||||
|
|
||||||
if [[ -n "${memo[$k]:-}" ]]; then
|
for ((j = 0; j < k; j++)); do
|
||||||
result=${memo[$k]}
|
tmp=$((a + b))
|
||||||
return
|
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
|
fi
|
||||||
|
|
||||||
fib $((k - 1))
|
"$bin" "$k"
|
||||||
a=$result
|
}
|
||||||
|
|
||||||
fib $((k - 2))
|
display_value() {
|
||||||
b=$result
|
local value=$1
|
||||||
|
local last=$2
|
||||||
|
|
||||||
memo[$k]=$((a + b))
|
if command -v cowsay >/dev/null 2>&1; then
|
||||||
result=${memo[$k]}
|
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
|
for ((i = 1; i <= n; i++)); do
|
||||||
fib "$i"
|
if ((USE_ASM)); then
|
||||||
value=$result
|
value="$(fib_asm "$i")"
|
||||||
|
else
|
||||||
|
value="$(fib_bash "$i")"
|
||||||
|
fi
|
||||||
|
|
||||||
if ((i < n)); then
|
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
|
sleep 1
|
||||||
clear
|
clear
|
||||||
else
|
else
|
||||||
printf '%s\n' "$value" | cowsay -e oo -T U
|
display_value "$value" 1
|
||||||
fi
|
fi
|
||||||
done
|
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