Skip to content

Instantly share code, notes, and snippets.

@Alex-JAML
Created April 11, 2025 06:32
Show Gist options
  • Select an option

  • Save Alex-JAML/cdaf21ee1af050edc0bb1116ba39ba77 to your computer and use it in GitHub Desktop.

Select an option

Save Alex-JAML/cdaf21ee1af050edc0bb1116ba39ba77 to your computer and use it in GitHub Desktop.
Codigo Assembly ARM64 para RaspbianOS
/*
* ---------------------------------------------------------------------------------
* Lenguajes de Interfaz en TECNM Campus ITT
* Autor: Jorge Alejandro Martinez Lopez
* Fecha: 2025-04-09
* Descripción: Calcula la suma de factoriales X! + Y! + Z! con entrada de usuario
* Implementación completa con subrutinas documentadas
* Demostración: [ASCIINEMA.ORG/XXXXXX]
* ---------------------------------------------------------------------------------
*/
/*
* ----------------------------------------------
* C# "Suma de Factoriales" (Referencia)
* ----------------------------------------------
* using System;
*
* class Program {
* static int Factorial(int n) {
* int result = 1;
* for (int i = 2; i <= n; i++) result *= i;
* return result;
* }
*
* static void Main() {
* Console.Write("Ingrese X: ");
* int x = int.Parse(Console.ReadLine());
* Console.Write("Ingrese Y: ");
* int y = int.Parse(Console.ReadLine());
* Console.Write("Ingrese Z: ");
* int z = int.Parse(Console.ReadLine());
*
* int resultado = Factorial(x) + Factorial(y) + Factorial(z);
* Console.WriteLine($"Resultado: {resultado}");
* }
* }
*/
.global _start
.section .data
msgX: .asciz "Ingrese X: " /* Mensaje para entrada X */
msgY: .asciz "Ingrese Y: " /* Mensaje para entrada Y */
msgZ: .asciz "Ingrese Z: " /* Mensaje para entrada Z */
msgRes: .asciz "Resultado: " /* Mensaje de resultado */
newline: .asciz "\n" /* Salto de línea */
buffer: .space 12 /* Buffer para entrada */
.section .bss
.lcomm x, 4 /* Variable para almacenar X */
.lcomm y, 4 /* Variable para almacenar Y */
.lcomm z, 4 /* Variable para almacenar Z */
.section .text
_start:
/* Leer y almacenar valor X */
ldr x0, =msgX
bl print_string
bl read_int
ldr x1, =x
str w0, [x1]
/* Leer y almacenar valor Y */
ldr x0, =msgY
bl print_string
bl read_int
ldr x1, =y
str w0, [x1]
/* Leer y almacenar valor Z */
ldr x0, =msgZ
bl print_string
bl read_int
ldr x1, =z
str w0, [x1]
/* Calcular X! + Y! + Z! */
ldr w0, =x
ldr w0, [x0]
bl factorial_iterativo
mov w19, w0 /* w19 = X! */
ldr w0, =y
ldr w0, [x0]
bl factorial_iterativo
add w19, w19, w0 /* w19 += Y! */
ldr w0, =z
ldr w0, [x0]
bl factorial_iterativo
add w19, w19, w0 /* w19 += Z! */
/* Mostrar resultado */
ldr x0, =msgRes
bl print_string
mov w0, w19
bl print_int
bl print_newline
/* Terminar programa */
mov x0, #0 /* Código de salida: éxito */
mov x8, #93 /* sys_exit */
svc #0
/* ============ SUBRUTINAS DOCUMENTADAS ============ */
/**
* factorial_iterativo - Calcula factorial de forma iterativa
* @w0: Número de entrada (n)
* Retorno: @w0 Factorial calculado (n!)
*/
factorial_iterativo:
cmp w0, #1
b.le factorial_done
mov w1, #1 /* Inicializar resultado */
mov w2, #2 /* Iniciar contador en 2 */
factorial_loop:
mul w1, w1, w2 /* Multiplicar acumulador */
add w2, w2, #1 /* Incrementar contador */
cmp w2, w0
b.le factorial_loop /* Continuar hasta n */
mov w0, w1 /* Devolver resultado */
factorial_done:
ret
/**
* print_string - Imprime un string terminado en null
* @x0: Dirección del string a imprimir
*/
print_string:
mov x1, x0 /* Cargar dirección del string */
mov x2, #0 /* Inicializar contador de longitud */
print_str_len:
ldrb w3, [x1, x2] /* Leer byte actual */
cbz w3, print_str_out /* Terminar en null */
add x2, x2, #1 /* Incrementar contador */
b print_str_len
print_str_out:
mov x0, #1 /* stdout */
mov x8, #64 /* sys_write */
svc #0
ret
/**
* read_int - Lee un entero desde stdin
* Retorno: @w0 Entero leído
*/
read_int:
mov x0, #0 /* stdin */
ldr x1, =buffer /* Buffer de entrada */
mov x2, #12 /* Tamaño máximo */
mov x8, #63 /* sys_read */
svc #0
ldr x1, =buffer /* Convertir ASCII a entero */
mov w0, #0 /* Inicializar resultado */
mov w3, #10 /* Base decimal */
read_int_conv:
ldrb w2, [x1], #1 /* Leer dígito */
cmp w2, #10 /* Verificar fin de línea */
beq read_int_end
sub w2, w2, #'0' /* Convertir ASCII a dígito */
madd w0, w0, w3, w2 /* resultado = resultado*10 + dígito */
b read_int_conv
read_int_end:
ret
/**
* print_int - Imprime un entero con signo
* @w0: Entero a imprimir
*/
print_int:
stp x29, x30, [sp, #-32]! /* Guardar registros */
mov x29, sp
mov x1, x29
add x1, x1, #31 /* Posicionar en buffer */
mov w2, #0
strb w2, [x1] /* Terminador nulo */
/* Manejar signo negativo */
cmp w0, #0
bge print_int_pos
mov w2, #'-'
sub x1, x1, #1
strb w2, [x1]
neg w0, w0
print_int_pos:
mov w3, #10 /* Base decimal */
cmp w0, #0
bne print_int_conv
mov w2, #'0' /* Caso especial para 0 */
sub x1, x1, #1
strb w2, [x1]
b print_int_disp
print_int_conv:
cmp w0, #0
beq print_int_disp
udiv w2, w0, w3 /* División por 10 */
msub w4, w2, w3, w0 /* Obtener residuo */
add w4, w4, #'0' /* Convertir a ASCII */
sub x1, x1, #1 /* Mover puntero */
strb w4, [x1] /* Almacenar dígito */
mov w0, w2 /* Actualizar cociente */
b print_int_conv
print_int_disp:
mov x0, #1 /* stdout */
mov x2, x29
add x2, x2, #32
sub x2, x2, x1 /* Calcular longitud */
mov x8, #64 /* sys_write */
svc #0
ldp x29, x30, [sp], #32 /* Restaurar registros */
ret
/**
* print_newline - Imprime un salto de línea
*/
print_newline:
ldr x0, =newline
b print_string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment