Skip to content

Instantly share code, notes, and snippets.

@FranciscoJCE
Last active April 11, 2025 06:35
Show Gist options
  • Select an option

  • Save FranciscoJCE/fcfab70f146112b4ec3efb34912cfe36 to your computer and use it in GitHub Desktop.

Select an option

Save FranciscoJCE/fcfab70f146112b4ec3efb34912cfe36 to your computer and use it in GitHub Desktop.
Codigo Assembly ARM64 para RaspbianOS
/*
* Programa: Cálculo de monto final con interés compuesto anual
* Autor: Francisco Javier Crisostomo Enciso
* Descripción: Calcula el monto final usando la fórmula M = C × (1 + r)^t
* Usa aritmética de enteros con factor de escalado de 10000
* Parámetros:
* - Capital inicial: 5000 (entero)
* - Tasa de interés: 4% (1.04 representado como 10400)
* - Tiempo: 5 años (entero)
*
* Ejemplo equivalente en C#:
* int capital = 5000;
* double factor = 1.04;
* int tiempo = 5;
* double monto = capital * Math.Pow(factor, tiempo);
* Console.WriteLine($"Monto final: {(int)monto}");
*
* Asciinema:https://asciinema.org/a/HWlS1iUxuYcDPUGbumWNc9gYe
*/
.section .data
capital: .quad 5000 // Capital inicial
factor: .quad 10400 // 1.04 * 10000 (tasa de interés escalada)
tiempo: .word 5 // Período en años
divisor: .quad 10000 // Factor de escalado
mensaje: .asciz "Monto final: "
newline: .asciz "\n"
.section .bss
.lcomm resultado_str, 64 // Buffer para el string de resultado
.section .text
.global _start
_start:
// Cargar valores iniciales
ldr x1, =capital
ldr x1, [x1] // x1 = capital (5000)
ldr x2, =factor
ldr x2, [x2] // x2 = factor (10400 = 1.04 * 10000)
ldr x3, =tiempo
ldr w3, [x3] // w3 = tiempo (5 años)
ldr x5, =divisor
ldr x5, [x5] // x5 = divisor (10000)
// Inicializar resultado en factor = 1.04^0 = 1.0000 = 10000
mov x4, 10000 // Factor compuesto inicial
potencia_loop:
cmp w3, #0 // Verificar si hemos terminado
beq calcular_monto
// Multiplicar por el factor y ajustar escala
mul x4, x4, x2 // x4 *= 1.04 (factor compuesto)
udiv x4, x4, x5 // Compensar escalado (dividir entre 10000)
sub w3, w3, #1 // Decrementar contador de años
b potencia_loop
calcular_monto:
// Calcular monto final: capital * factor
mul x6, x1, x4 // monto = capital * factor compuesto
udiv x6, x6, x5 // Quitar escala para obtener valor final
// Mostrar mensaje "Monto final: "
mov x0, #1 // stdout
ldr x1, =mensaje
mov x2, #13 // longitud del mensaje
mov x8, #64 // syscall write
svc #0
// Convertir el resultado numérico a string
mov x0, x6 // pasar el resultado a convertir
bl int_to_str
// Mostrar el resultado numérico
mov x0, #1 // stdout
ldr x1, =resultado_str
mov x2, #64 // longitud máxima
mov x8, #64 // syscall write
svc #0
// Imprimir salto de línea final
mov x0, #1
ldr x1, =newline
mov x2, #1
mov x8, #64
svc #0
// Terminar el programa
mov x8, #93 // syscall exit
mov x0, #0 // código de salida 0
svc #0
// Función: int_to_str
// Convierte un entero en su representación ASCII
int_to_str:
ldr x1, =resultado_str
mov x2, #0 // contador de dígitos
mov x3, #10 // divisor
mov x4, x0 // copia del número
// Caso especial para cero
cbz x4, poner_cero
conv_loop:
udiv x5, x4, x3 // x5 = número / 10
msub x6, x5, x3, x4 // x6 = número % 10 (dígito)
add x6, x6, #'0' // convertir a ASCII
strb w6, [x1, x2] // almacenar dígito
add x2, x2, #1 // incrementar contador
mov x4, x5 // actualizar número
cbnz x4, conv_loop // continuar si no es cero
// Invertir la cadena
mov x5, #0 // índice inicial
sub x6, x2, #1 // índice final
inv_loop:
cmp x5, x6
b.ge listo // terminar si los índices se cruzan
ldrb w7, [x1, x5] // intercambiar dígitos
ldrb w8, [x1, x6]
strb w8, [x1, x5]
strb w7, [x1, x6]
add x5, x5, #1 // mover índices
sub x6, x6, #1
b inv_loop
poner_cero:
mov w5, #'0'
strb w5, [x1] // almacenar '0'
mov x2, #1 // longitud = 1
listo:
mov w5, #0
strb w5, [x1, x2] // terminador nulo
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment