Este código en ARM64 Assembly calcula el factorial de un número (en este caso, 5), lo convierte en una cadena de texto, y lo imprime por pantalla usando llamadas al sistema (syscalls).
📦 .section .data
buffer: .space 20 // Reservamos espacio para un buffer de 20 bytes
Aquí se declara un espacio de memoria llamado buffer de 20 bytes. Este se usará para guardar el número convertido en string.
⚙️ .section .text y _start
.global _start
_start:
mov x0, #5 // Número cuyo factorial queremos calcular
mov x1, #1 // Acumulador (resultado)
-
x0 = 5: el número del cual se calculará el factorial.
-
x1 = 1: será el acumulador del resultado (1 * 2 * 3 * ... * x0).
🔁 Bucle para calcular el factorial
factorial_loop:
cmp x0, #1
ble end_factorial
mul x1, x1, x0
sub x0, x0, #1
b factorial_loop
-
Compara
x0 con 1.
-
Si
x0 ≤ 1, termina el bucle (ble end_factorial).
-
Multiplica el acumulador (
x1) por x0.
-
Decrementa
x0.
-
Repite.
✅ Resultado: el factorial de 5 (5×4×3×2×1 = 120) estará en x1.
🔢 Convertir el entero en x1 a string
end_factorial:
mov x0, x1 // Pasamos el resultado a x0
ldr x1, =buffer // Dirección del buffer
bl int_to_str // Llamamos a la función de conversión
-
Prepara los argumentos para la función
int_to_str(x0, x1):
-
x0: número a convertir
-
x1: puntero al buffer donde guardar la cadena
🖨️ Escribir el string en pantalla
mov x0, #1 // stdout (fd = 1)
ldr x1, =buffer // puntero al string
mov x2, #20 // Longitud máxima estimada
mov x8, #64 // syscall write
svc #0
-
Realiza una syscall para escribir en
stdout:
-
x0: descriptor de archivo (1 = stdout)
-
x1: puntero al mensaje
-
x2: longitud máxima (20)
-
x8: número de syscall 64 (write)
-
svc #0: realiza la syscall
🛑 Salida del programa
mov x8, #93 // syscall exit
svc #0
-
x8 = 93: syscall exit.
-
svc #0: llamada al sistema.
🧠 Función: int_to_str
Convierte un número (en x0) a cadena en el buffer (x1).
int_to_str:
mov x2, x1
add x1, x1, #19 // Final del buffer
strb wzr, [x1] // Escribe terminador nulo '\0'
sub x1, x1, #1 // Retrocede para empezar a escribir
mov x5, #10 // Para división por 10
Ahora entra en un bucle:
int_to_str_loop:
mov x3, x0
udiv x0, x3, x5 // Cociente
msub x4, x0, x5, x3 // Resto (x4 = x3 - x0 * 10)
add x4, x4, #48 // Convierte a ASCII
strb w4, [x1] // Guarda carácter
sub x1, x1, #1 // Retrocede el puntero
cmp x0, #0
bne int_to_str_loop
Este bucle:
-
Divide el número por 10 (
x0 = x0 / 10).
-
Obtiene el dígito más a la derecha (
x4 = resto).
-
Lo convierte a su equivalente ASCII (
+48).
-
Lo guarda en el buffer.
-
Se repite hasta que el número sea 0.
Finalmente:
add x1, x1, #1 // Ajusta el puntero al inicio del string
ret
🧪 Ejemplo de ejecución
-
Calcula factorial(5) = 120
-
Convierte 120 a string:
'120\0'
-
Lo escribe en pantalla.