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