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