.global _start
.section .bss
input: .skip 20
buffer: .skip 32
.section .rodata
newline: .asciz "\n"
.section .text
_start:
// Leer número desde teclado
mov x0, #0 // STDIN
ldr x1, =input
mov x2, #20
mov x8, #63 // syscall read
svc 0
// Convertir string a entero en x20
ldr x1, =input
mov x20, #0 // acumulador
mov x2, #0
mov x9, #10 // constante 10
parse_input:
ldrb w3, [x1, x2]
cmp w3, #10
beq end_parse
sub w3, w3, #'0'
uxtw x4, w3
mul x20, x20, x9
add x20, x20, x4
add x2, x2, #1
b parse_input
end_parse:
// F(0) = 0
cmp x20, #0
bne continue
mov x7, #0
b print_result
continue:
// F(1) = 1
cmp x20, #1
bne start_fibo
mov x7, #1
b print_result
// ----------------------------------------------------
// Matriz base: A = {{1,1},{1,0}}, B = resultado
// Almacenes en registros:
// A: x0 x1
// x2 x3
// B: x4 x5
// x6 x7
// ----------------------------------------------------
start_fibo:
// Inicializar matriz base A
mov x0, #1 // A[0][0]
mov x1, #1 // A[0][1]
mov x2, #1 // A[1][0]
mov x3, #0 // A[1][1]
// Inicializar identidad B
mov x4, #1 // B[0][0]
mov x5, #0 // B[0][1]
mov x6, #0 // B[1][0]
mov x7, #1 // B[1][1]
mov x8, x20 // x8 = n
sub x8, x8, #1 // n - 1
fib_power_loop:
// while (n > 0)
cmp x8, #0
beq done_power
// if (n % 2 == 1) → B = B * A
and x9, x8, #1
cmp x9, #0
beq skip_mult
bl matrix_mult_BA
skip_mult:
// A = A * A
bl matrix_mult_AA
// n = n / 2
lsr x8, x8, #1
b fib_power_loop
done_power:
// Resultado en x5 = B[0][1] = F(n)
mov x7, x5
// --------------------------------
// Imprimir número x7
// --------------------------------
print_result:
ldr x5, =buffer
add x5, x5, #31
mov x2, #0
mov x10, x7
mov x9, #10
conv_loop:
udiv x7, x10, x9
mul x8, x7, x9
sub x4, x10, x8
add x4, x4, #'0'
strb w4, [x5]
sub x5, x5, #1
add x2, x2, #1
mov x10, x7
cmp x10, #0
bne conv_loop
add x5, x5, #1
mov w3, #'\n'
strb w3, [x5, x2]
add x2, x2, #1
mov x0, #1
mov x1, x5
mov x8, #64
svc 0
// salir
mov x0, #0
mov x8, #93
svc 0
// ----------------------------------------------------
// Subrutina: matrix_mult_BA → B = B * A
// Entrada: A = x0..x3, B = x4..x7
// Salida: B actualizada
// ----------------------------------------------------
matrix_mult_BA:
// Guardar copias
mov x11, x4
mov x12, x5
mov x13, x6
mov x14, x7
// B * A
mul x4, x11, x0 // B[0][0] = b00*a00
madd x4, x12, x2, x4 // + b01*a10
mul x5, x11, x1 // B[0][1] = b00*a01
madd x5, x12, x3, x5
mul x6, x13, x0 // B[1][0] = b10*a00
madd x6, x14, x2, x6
mul x7, x13, x1 // B[1][1] = b10*a01
madd x7, x14, x3, x7
ret
// ----------------------------------------------------
// Subrutina: matrix_mult_AA → A = A * A
// Entrada/Salida: A en x0..x3
// ----------------------------------------------------
matrix_mult_AA:
mov x11, x0
mov x12, x1
mov x13, x2
mov x14, x3
mul x0, x11, x11
madd x0, x12, x13, x0
mul x1, x11, x12
madd x1, x12, x14, x1
mul x2, x13, x11
madd x2, x14, x13, x2
mul x3, x13, x12
madd x3, x14, x14, x3
ret