Skip to content

Instantly share code, notes, and snippets.

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

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

Select an option

Save FranciscoJCE/26ca948407ae26e1a20065b9ad90892b to your computer and use it in GitHub Desktop.
Codigo Assembly ARM64 para RaspbianOS
/*
* Programa: Calcular la tasa de retorno anual compuesta
* Autor: Francisco Javiier Crisostomo Enciso
* Descripción: Calcula la tasa de retorno usando la fórmula r = (M/C)^(1/t) - 1
* Parámetros:
* - Capital inicial (C): 1000
* - Monto final (M): 1500
* - Tiempo (t): 3 años
* Uso de aritmética entera con escalado ×10000 para precisión
*
* Asciinema:https://asciinema.org/a/ifL8fevcvjAcbtLPMUMGr66Yi
*/
.section .data
capital: .quad 1000 // Capital inicial (C)
monto: .quad 1500 // Monto final (M)
tiempo: .word 3 // Período en años (t)
escala: .quad 10000 // Factor de escalado
mensaje: .asciz "Tasa de retorno: "
porcentaje: .asciz " %\n"
.section .bss
.lcomm resultado_str, 64 // Buffer para el string de resultado
.section .text
.global _start
_start:
// ======================================
// Cargar valores iniciales
// ======================================
ldr x1, =monto
ldr x1, [x1] // x1 = monto final (1500)
ldr x2, =capital
ldr x2, [x2] // x2 = capital inicial (1000)
ldr x3, =escala
ldr x3, [x3] // x3 = factor de escala (10000)
// ======================================
// Calcular (M/C) escalado ×10000
// ======================================
mul x1, x1, x3 // x1 = monto × 10000
udiv x4, x1, x2 // x4 = (M/C) × 10000
// ======================================
// Calcular raíz cúbica (aproximación entera)
// ======================================
mov x0, x4 // x0 = base para cálculo de raíz
mov w1, #3 // raíz cúbica (t=3 años)
bl raiz_entera // resultado en x0
// ======================================
// Calcular tasa final: (raíz - 1.0000) × 100%
// ======================================
sub x0, x0, x3 // r = r - 1.0000 (escalado)
// Ejemplo: 11450 - 10000 = 1450 (14.50%)
// ======================================
// Mostrar mensaje "Tasa de retorno: "
// ======================================
mov x0, #1 // stdout
ldr x1, =mensaje
mov x2, #18 // longitud del mensaje
mov x8, #64 // syscall write
svc #0
// ======================================
// Convertir el resultado numérico a string
// ======================================
mov x0, x0 // 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
// ======================================
// Mostrar símbolo de porcentaje
// ======================================
mov x0, #1
ldr x1, =porcentaje
mov x2, #3 // " %\n"
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: raiz_entera
// Calcula la raíz n-ésima entera aproximada
// Entrada:
// x0 = número base
// w1 = índice de la raíz
// Salida:
// x0 = raíz entera aproximada
// ============================================
raiz_entera:
mov x2, #1 // inicializar contador de raíz
raiz_loop:
mov x3, x2 // x3 = candidato a raíz
mov w4, w1 // w4 = exponente (copia)
pot_loop:
cmp w4, #1
beq pot_fin // si exponente es 1, terminar
mul x3, x3, x2 // elevar al cuadrado
sub w4, w4, #1 // decrementar exponente
b pot_loop
pot_fin:
cmp x3, x0
b.gt raiz_listo // si x3 > x0, encontramos el límite
add x2, x2, #1 // incrementar candidato a raíz
b raiz_loop
raiz_listo:
sub x0, x2, #1 // ajustar al valor anterior
ret
// ============================================
// Función: int_to_str
// Convierte un entero en su representación ASCII
// Entrada:
// x0 = número a convertir
// Salida:
// resultado_str = string con el número
// ============================================
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 (los dígitos se generan en orden inverso)
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