Programa 16: Calculador del Máximo Común Divisor (Algoritmo de Euclides) en Asembly ARM64 - Alejandro Suarez
by pepinisillo
GNU/Linux
•
xterm
•
bash
87 views
📌 Demostración: Calculador del Máximo Común Divisor en ARM64 Assembly
💻 Lenguajes de Interfaz en TECNM Campus ITT
👨💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/08
🎯 Descripción
Este programa calcula el máximo común divisor de dos números.
La implementación se realiza en:
✅ Assembly ARM64 para RaspbianOS en Raspberry Pi
🔧 Compilación en Raspberry Pi (ARM64)
as mcd.s -o mcd.o
ld mcd.o -o mcd
▶️ Ejecución
./mcd
👀 Código fuente
🔗 Código fuente en Gist: Programa 16 Cálculo del Máximo Común Divisor (Algoritmo de Euclides) 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/08 |
| • Descripción: Programa que calcula el Máximo Común Divisor de |
| dos numeros en GO y Assembly ARM64 para RaspbianOS. |
| • Demostración: |
| https://asciinema.org/a/713365 |
| • Compilación (Raspberry Pi ARM64): |
| as mcd.s -o mcd.o |
| ld mcd.o -o mcd |
| • Ejecución: ./mcd |
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje GO •°•═══════
package main
import (
"fmt"
"os"
)
func gcd(a, b int) int {
for b != 0 {
t := b
b = a % b
a = t
}
return a
}
func main() {
num1 := 48
num2 := 18
fmt.Printf("Calculando MCD de %d y %d\n", num1, num2)
result := gcd(num1, num2)
fmt.Printf("El MCD es: %d\n", result)
os.Exit(0)
}
════════════════════•°• ☆ •°•══════════════════════════════
/*
/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */
.global _start // Punto de entrada global
.data
// Números para calcular el MCD
num1:
.word 48 // Primer número
num2:
.word 18 // Segundo número
// Mensajes
msg1:
.ascii "Calculando MCD de "
msg1_len = . - msg1
msg2:
.ascii " y "
msg2_len = . - msg2
msg3:
.ascii "El MCD 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
// 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:
// Resultado en w19, mostrar mensaje
mov x0, #1
adr x1, msg3
mov x2, #msg3_len
mov x8, #64
svc #0
// Mostrar resultado
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