Programa 27: Ordenamiento de arreglo con números por el ordenamiento de burbuja en Assembly ARM64 - Alejandro Suarez
by pepinisillo
GNU/Linux
•
xterm
•
bash
86 views
📌 Demostración: Ordenamiento de arreglo con números por el ordenamiento de burbuja en ARM64 Assembly
💻 Lenguajes de Interfaz en TECNM Campus ITT
👨💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/09
🎯 Descripción
Este programa ordena un arreglo de números por el ordenamiento burbuja y lo muestra en la terminal.
La implementación se realiza en:
✅ Assembly ARM64 para RaspbianOS en Raspberry Pi
🔧 Compilación en Raspberry Pi (ARM64)
as burbuja.s -o burbuja.o
ld burbuja.o -o burbuja
▶️ Ejecución
./burbuja
👀 Código fuente
🔗 Código fuente en Gist: Programa 27 Ordena un arreglo de numeros con ordenamiento Burbuja 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 ordena un arreglo de numeros con el |
| ordenamiento de burbuja en Rust y Assembly ARM64 para RaspbianOS. |
| • Demostración: |
| https://asciinema.org/a/713468 |
| • Compilación (Raspberry Pi ARM64): |
| as burbuja.s -o burbuja.o |
| ld burbuja.o -o burbuja |
| • Ejecución: ./burbuja |
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje Rust •°•═══════
fn main() {
let mut array = [42, 17, 93, 5, 81, 30, 67, 12, 22, 51];
println!("Arreglo desordenado: {:?}", array);
bubble_sort(&mut array);
println!("Arreglo ordenado: {:?}", array);
}
fn bubble_sort(arr: &mut [i32]) {
let n = arr.len();
for i in 0..n {
for j in 0..n-i-1 {
if arr[j] > arr[j+1] {
arr.swap(j, j+1);
}
}
}
}
════════════════════•°• ☆ •°•══════════════════════════════
/*
/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */
.data
// Definición del arreglo desordenado
array: .word 42, 17, 93, 5, 81, 30, 67, 12, 22, 51
array_size: .word 10
// Mensajes para mostrar
msg_unsorted: .ascii "Arreglo desordenado: ["
msg_sorted: .ascii "Arreglo ordenado: ["
msg_comma: .ascii ", "
msg_close: .ascii "]\n"
newline: .ascii "\n"
.text
.global _start
_start:
// Guardar la dirección del arreglo y su tamaño
adr x19, array
ldr w20, array_size
// Mostrar el arreglo desordenado
bl print_unsorted_array
// Aplicar el algoritmo de ordenamiento bubble sort
bl bubble_sort
// Mostrar el arreglo ordenado
bl print_sorted_array
// Terminar programa
b exit
//////////////////////////////////////////
// Subrutina de bubble sort
//////////////////////////////////////////
bubble_sort:
// Guardar dirección de retorno
str lr, [sp, #-16]!
// x19 = dirección del arreglo
// w20 = tamaño del arreglo
// Iniciar bucle externo (i va desde 0 hasta n-1)
mov w21, #0 // i = 0
outer_loop:
// Comprobar si hemos terminado el bucle externo
sub w22, w20, #1 // n-1
cmp w21, w22
b.ge bubble_sort_end
// Iniciar bucle interno (j va desde 0 hasta n-i-1)
mov w23, #0 // j = 0
inner_loop:
// Comprobar si hemos terminado el bucle interno
sub w24, w20, w21 // n-i
sub w24, w24, #1 // n-i-1
cmp w23, w24
b.ge outer_loop_next
// Cargar array[j] y array[j+1]
lsl x25, x23, #2 // j*4 (cada entero es de 4 bytes)
add x25, x19, x25 // dirección de array[j]
ldr w26, [x25] // w26 = array[j]
add x27, x25, #4 // dirección de array[j+1]
ldr w28, [x27] // w28 = array[j+1]
// Comparar array[j] y array[j+1]
cmp w26, w28
b.le inner_loop_next // Si array[j] <= array[j+1], no hay intercambio
// Intercambiar array[j] y array[j+1]
str w28, [x25] // array[j] = array[j+1]
str w26, [x27] // array[j+1] = array[j]
inner_loop_next:
// j++
add w23, w23, #1
b inner_loop
outer_loop_next:
// i++
add w21, w21, #1
b outer_loop
bubble_sort_end:
// Restaurar dirección de retorno y volver
ldr lr, [sp], #16
ret
//////////////////////////////////////////
// Subrutina para imprimir arreglo desordenado
//////////////////////////////////////////
print_unsorted_array:
// Guardar dirección de retorno
str lr, [sp, #-16]!
// Imprimir mensaje inicial
mov x0, #1 // STDOUT
adr x1, msg_unsorted // Mensaje
mov x2, #22 // Longitud
mov x8, #64 // syscall write
svc #0
// Llamar a la subrutina para imprimir el arreglo
bl print_array_content
// Restaurar dirección de retorno y volver
ldr lr, [sp], #16
ret
//////////////////////////////////////////
// Subrutina para imprimir arreglo ordenado
//////////////////////////////////////////
print_sorted_array:
// Guardar dirección de retorno
str lr, [sp, #-16]!
// Imprimir mensaje inicial
mov x0, #1 // STDOUT
adr x1, msg_sorted // Mensaje
mov x2, #22 // Longitud
mov x8, #64 // syscall write
svc #0
// Llamar a la subrutina para imprimir el arreglo
bl print_array_content
// Restaurar dirección de retorno y volver
ldr lr, [sp], #16
ret
//////////////////////////////////////////
// Subrutina para imprimir contenido del arreglo
//////////////////////////////////////////
print_array_content:
// Guardar dirección de retorno y registros utilizados
stp lr, x19, [sp, #-16]!
stp x20, x21, [sp, #-16]!
stp x22, x23, [sp, #-16]!
// x19 ya contiene la dirección del arreglo
// w20 ya contiene el tamaño del arreglo
// Inicializar índice
mov w21, #0 // índice i = 0
print_element_loop:
// Comprobar si hemos impreso todos los elementos
cmp w21, w20
b.ge print_array_end
// Cargar y convertir elemento actual a ASCII
lsl x22, x21, #2 // x22 = i * 4
add x22, x19, x22 // x22 = dirección del elemento i-ésimo
ldr w23, [x22] // w23 = array[i]
// Reservar espacio para la conversión
sub sp, sp, #16
mov x22, sp
// Convertir entero a cadena
mov w24, w23 // Valor a convertir
mov x25, #0 // Contador de dígitos
convert_digit_loop:
// Dividir por 10 para obtener el último dígito
mov w26, #10
udiv w27, w24, w26 // w27 = w24 / 10
msub w28, w27, w26, w24 // w28 = w24 - (w27 * 10) = dígito
// Convertir a ASCII y guardar
add w28, w28, #'0'
strb w28, [x22, x25]
add x25, x25, #1
// Actualizar valor y comprobar si terminamos
mov w24, w27
cbnz w24, convert_digit_loop
// Invertir la cadena
mov x26, #0 // Índice inicio
sub x27, x25, #1 // Índice fin
reverse_digit_loop:
cmp x26, x27
b.ge print_this_element
// Intercambiar caracteres
ldrb w28, [x22, x26]
ldrb w29, [x22, x27]
strb w29, [x22, x26]
strb w28, [x22, x27]
// Actualizar índices
add x26, x26, #1
sub x27, x27, #1
b reverse_digit_loop
print_this_element:
// Imprimir número
mov x0, #1
mov x1, x22
mov x2, x25
mov x8, #64
svc #0
// Liberar espacio de conversión
add sp, sp, #16
// Incrementar índice
add w21, w21, #1
// Comprobar si es el último elemento
cmp w21, w20
b.ge print_close_bracket
// Si no es el último, imprimir separador
mov x0, #1
adr x1, msg_comma
mov x2, #2
mov x8, #64
svc #0
b print_element_loop
print_close_bracket:
// Imprimir cierre del arreglo
mov x0, #1
adr x1, msg_close
mov x2, #2
mov x8, #64
svc #0
print_array_end:
// Restaurar registros y volver
ldp x22, x23, [sp], #16
ldp x20, x21, [sp], #16
ldp lr, x19, [sp], #16
ret
//////////////////////////////////////////
// Subrutina para salir del programa
//////////////////////////////////////////
exit:
// Salir con código 0
mov x0, #0
mov x8, #93 // syscall exit
svc #0