Programa 29 Calcula el Máximo Común Múltiplo entre dos números y muestra el resultado en terminal en Assemby ARM64 - Alejandro Suarez
by pepinisillo
GNU/Linux
•
xterm
•
bash
86 views
📌 Demostración: Calcula el Máximo Común Múltiplo entre dos números y muestra el resultado en terminal en ARM64 Assembly
💻 Lenguajes de Interfaz en TECNM Campus ITT
👨💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/09
🎯 Descripción
Este programa calcula el Máximo Común Múltiplo entre dos números y muestra el resultado en terminal.
La implementación se realiza en:
✅ Assembly ARM64 para RaspbianOS en Raspberry Pi
🔧 Compilación en Raspberry Pi (ARM64)
as mcmo.s -o mcm.o
ld mcm.o -o mcm
▶️ Ejecución
./mcm
👀 Código fuente
🔗 Código fuente en Gist: Programa 29 Calculador del Maximo Comun Multiplo de dos numeros mostrando resultado en terminal Código Assembly ARM64 para RaspbianOS
/*
______ ____ ____ __ __
/\ _ \/\ _`\ /'\_/`\ /'___\/\ \\ \
\ \ \L\ \ \ \L\ \/\ \/\ \__/\ \ \\ \
\ \ __ \ \ , /\ \ \__\ \ \ _``\ \ \\ \_
\ \ \/\ \ \ \\ \\ \ \_/\ \ \ \L\ \ \__ ,__\
\ \_\ \_\ \_\ \_\ \_\\ \_\ \____/\/_/\_\_/
\/_/\/_/\/_/\/ /\/_/ \/_/\/___/ \/_/
♡ ∩_∩
(„• ֊ •„)♡
| ̄U U ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
| • Lenguajes de Interfaz en TECNM Campus ITT |
| • Autor: Alejandro Suarez Sandoval |
| • Fecha: 2025/04/09 |
| • Descripción: Programa que calcula el Maximo Comun |
| Multiplo de dos numeros en Python y Assembly ARM64 para RaspbianOS. |
| • Demostración: |
| https://asciinema.org/a/713684 |
| • Compilación (Raspberry Pi ARM64): |
| as mcm.s -o mcm.o |
| ld mcm.o -o mcm |
| • Ejecución: ./mcm |
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje Python •°•═══════
import sys
import math
def num_to_ascii(num):
return str(num)
num1 = 48
num2 = 18
print(f"Calculando MCM de {num1} y {num2}")
gcd = math.gcd(num1, num2)
lcm = (num1 * num2) // gcd
print(f"El MCM es: {lcm}")
sys.exit(0)
════════════════════•°• ☆ •°•══════════════════════════════
/*
/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */
.global _start // Punto de entrada global
.data
// Números para calcular el MCM
num1:
.word 48 // Primer número
num2:
.word 18 // Segundo número
// Mensajes
msg1:
.ascii "Calculando MCM de "
msg1_len = . - msg1
msg2:
.ascii " y "
msg2_len = . - msg2
msg3:
.ascii "El MCM es: "
msg3_len = . - msg3
newline:
.ascii "\n"
newline_len = . - newline
// Búfer para convertir números a texto
buffer:
.skip 20
.text
_start:
// Cargar los números
adr x19, num1
ldr w19, [x19] // w19 = primer número
adr x20, num2
ldr w20, [x20] // w20 = segundo número
// Guardar copias de los números originales para cálculo del MCM
mov w23, w19 // w23 = primer número (copia)
mov w24, w20 // w24 = segundo número (copia)
// Mostrar mensaje inicial
mov x0, #1
adr x1, msg1
mov x2, #msg1_len
mov x8, #64
svc #0
// Mostrar primer número
mov x24, x19
bl num_to_ascii
// Mostrar "y"
mov x0, #1
adr x1, msg2
mov x2, #msg2_len
mov x8, #64
svc #0
// Mostrar segundo número
mov x24, x20
bl num_to_ascii
// Mostrar nueva línea
mov x0, #1
adr x1, newline
mov x2, #newline_len
mov x8, #64
svc #0
// Calcular MCD usando el algoritmo de Euclides
gcd_loop:
// Si b = 0, terminamos (el resultado está en a)
cmp w20, #0
b.eq gcd_done
// t = b
mov w21, w20
// b = a % b
sdiv w22, w19, w20 // w22 = a / b
msub w20, w22, w20, w19 // w20 = a - (a/b) * b = a % b
// a = t
mov w19, w21
b gcd_loop
gcd_done:
// MCD en w19, ahora calculemos el MCM = (a*b)/mcd
// Calcular producto a*b
mul w25, w23, w24 // w25 = primer número * segundo número
// Dividir por el MCD para obtener el MCM
udiv w19, w25, w19 // w19 = (a*b)/mcd = MCM
// Resultado del MCM en w19, mostrar mensaje
mov x0, #1
adr x1, msg3
mov x2, #msg3_len
mov x8, #64
svc #0
// Mostrar resultado del MCM
mov x24, x19
bl num_to_ascii
// Mostrar nueva línea
mov x0, #1
adr x1, newline
mov x2, #newline_len
mov x8, #64
svc #0
// Salir del programa
mov x0, #0
mov x8, #93
svc #0
// Subrutina para convertir número a ASCII y mostrarlo
num_to_ascii:
// Preparar para convertir el número a texto
mov x25, x24 // Copiar número a x25
adr x26, buffer // x26 = puntero al búfer
add x26, x26, #19 // Empezar desde el final del búfer
mov x27, #10 // x27 = base 10 para división
// Caso especial si el número es 0
cbnz x25, convert_loop
mov w28, '0' // Carácter ASCII '0'
strb w28, [x26]
sub x26, x26, #1
b end_convert
convert_loop:
// Comprobar si el número es 0
cbz x25, end_convert
// Obtener el último dígito (número % 10)
udiv x28, x25, x27 // x28 = x25 / 10
msub x29, x28, x27, x25 // x29 = x25 - (x28 * 10) = x25 % 10
// Convertir dígito a ASCII y guardarlo
add w29, w29, #'0' // Convertir a carácter ASCII
strb w29, [x26] // Guardar en búfer
sub x26, x26, #1 // Mover puntero
// Actualizar número para siguiente iteración
mov x25, x28 // Número = número / 10
b convert_loop
end_convert:
// Calcular longitud de la cadena resultante
add x26, x26, #1 // Ajustar puntero al primer dígito
adr x25, buffer
add x25, x25, #20
sub x2, x25, x26 // x2 = longitud de la cadena
// Imprimir número
mov x0, #1 // File descriptor: 1 para stdout
mov x1, x26 // Dirección del búfer
mov x8, #64 // Syscall número 64: write
svc #0 // Llamada al sistema
ret