GNU/Linux xterm bash 89 views

📌 Demostración: Encuentra el número más grande de un arreglo en ARM64 Assembly

💻 Lenguajes de Interfaz en TECNM Campus ITT
👨‍💻 Autor: Alejandro Suarez Sandoval
📅 Fecha: 2025/04/09

🎯 Descripción

Este programa encuentra el número más grande dentro de un array dado en memoria.
La implementación se realiza en:

Assembly ARM64 para RaspbianOS en Raspberry Pi

🔧 Compilación en Raspberry Pi (ARM64)

as mayor_array.s -o mayor_array.o  
ld mayor_array.o -o mayor_array

▶️ Ejecución

./mayor_array

👀 Código fuente

🔗 Código fuente en Gist: Programa 26 Encuentra el numero mas grande de un arreglo 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 encuentra el numero mas grande             | 
|   en un array en PHP y Assembly ARM64 para RaspbianOS.                 | 
| • Demostración:                                                        |
|   https://asciinema.org/a/713463                                       |
| • Compilación (Raspberry Pi ARM64):                                    |  
|     as mayor_array.s -o mayor_array.o                                  |  
|     ld mayor_array.o -o mayor_array                                    |  
| • Ejecución: ./mayor_array                                             |  
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄                                        

⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════•°• Demostración Código en lenguaje PHP •°•═══════

<?php

$array = [15, 7, 22, 9, 35, 4, 18, 30, 25, 10];
$array_size = count($array);

echo "El arreglo es: ";
foreach ($array as $number) {
    echo $number . " ";
}
echo "\n";

$max = $array[0]; 
for ($i = 1; $i < $array_size; $i++) {
    if ($array[$i] > $max) {
        $max = $array[$i];
    }
}

echo "El número mayor es: " . $max . "\n";

exit(0);
?>

════════════════════•°• ☆ •°•══════════════════════════════
/*

/* ⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂⠁⠁⠂⠄⠄⠂ ⠂⠄⠄⠂☆
═════════════•°• Código en ARM64 Assembly •°•═════════════ */

// Programa ARM64 para encontrar el número mayor en un arreglo
// y mostrar el arreglo junto con el número mayor

.data
    // Definición del arreglo
    array:      .word   25, 7, 89, 12, 45, 17, 92, 34, 6, 53
    array_size: .word   10
    
    // Mensajes para mostrar
    msg_array:  .ascii  "El arreglo es: ["
    msg_comma:  .ascii  ", "
    msg_close:  .ascii  "]\n"
    msg_max:    .ascii  "El número mayor en el arreglo es: "
    newline:    .ascii  "\n"

.text
.global _start

_start:
    // Cargar la dirección del arreglo y su tamaño
    adr     x0, array
    ldr     w1, array_size
    
    // Inicializar el valor máximo con el primer elemento
    ldr     w2, [x0]    // w2 contendrá el valor máximo
    
    // Configurar contador de bucle e índice
    mov     w3, #1      // índice i = 1 (comenzamos desde el segundo elemento)
    
find_max_loop:
    // Comprobar si hemos revisado todos los elementos
    cmp     w3, w1
    b.ge    print_array // Si terminamos, vamos a imprimir el arreglo
    
    // Cargar el elemento actual
    lsl     x4, x3, #2      // x4 = i * 4 (cada elemento es de 4 bytes)
    add     x4, x0, x4      // x4 = dirección del elemento i-ésimo
    ldr     w5, [x4]        // w5 = array[i]
    
    // Comparar con el máximo actual
    cmp     w5, w2
    b.le    next_element    // Si no es mayor, continuar
    
    // Actualizar el máximo
    mov     w2, w5
    
next_element:
    // Incrementar índice y continuar
    add     w3, w3, #1
    b       find_max_loop

print_array:
    // Guardar el máximo para usar más tarde
    mov     w10, w2
    
    // Imprimir mensaje inicial del arreglo
    mov     x0, #1          // STDOUT
    adr     x1, msg_array   // Mensaje
    mov     x2, #16         // Longitud
    mov     x8, #64         // syscall write
    svc     #0
    
    // Inicializar para recorrer e imprimir el arreglo
    adr     x19, array      // x19 = dirección del arreglo
    mov     w20, #0         // w20 = índice
    ldr     w21, array_size // w21 = tamaño del arreglo
    
print_loop:
    // Comprobar si hemos impreso todos los elementos
    cmp     w20, w21
    b.ge    print_max    // Si terminamos, imprimir el máximo
    
    // Cargar y convertir elemento actual a ASCII
    lsl     x22, x20, #2        // x22 = i * 4
    add     x22, x19, x22       // x22 = dirección del elemento i-ésimo
    ldr     w23, [x22]          // w23 = array[i]
    
    // Convertir número a string (se usa una simplificación)
    // Para este ejemplo, asumimos números de hasta 3 dígitos
    sub     sp, sp, #16         // Reservar espacio en la pila
    mov     x22, sp             // x22 = dirección del buffer
    
    // Convertir el número a string (algoritmo simple)
    mov     w24, w23            // w24 = número a convertir
    mov     x25, #0             // x25 = contador de dígitos (cambiado a x25)
    
convert_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 dígito a ASCII y guardar
    add     w28, w28, #'0'      // Convertir a ASCII
    strb    w28, [x22, x25]     // Guardar en buffer (corregido a x25)
    add     x25, x25, #1        // Incrementar contador
    
    // Actualizar número y comprobar si terminamos
    mov     w24, w27            // w24 = w24 / 10
    cbnz    w24, convert_loop   // Si aún quedan dígitos, continuar
    
    // Invertir la cadena (ya que los dígitos se generan al revés)
    mov     x26, #0             // inicio (cambiado a x26)
    sub     x27, x25, #1        // fin (cambiado a x27)
    
reverse_loop:
    cmp     x26, x27
    b.ge    print_number
    
    ldrb    w28, [x22, x26]     // temp1 = str[inicio] (corregido a x26)
    ldrb    w29, [x22, x27]     // temp2 = str[fin] (corregido a x27)
    strb    w29, [x22, x26]     // str[inicio] = temp2 (corregido a x26)
    strb    w28, [x22, x27]     // str[fin] = temp1 (corregido a x27)
    
    add     x26, x26, #1        // inicio++
    sub     x27, x27, #1        // fin--
    b       reverse_loop
    
print_number:
    // Imprimir el número
    mov     x0, #1
    mov     x1, x22
    mov     x2, x25
    mov     x8, #64
    svc     #0
    
    // Liberar el buffer
    add     sp, sp, #16
    
    // Imprimir separador, excepto para el último elemento
    add     w20, w20, #1
    cmp     w20, w21
    b.ge    close_array
    
    mov     x0, #1
    adr     x1, msg_comma
    mov     x2, #2
    mov     x8, #64
    svc     #0
    
    b       print_loop
    
close_array:
    // Imprimir cierre del arreglo
    mov     x0, #1
    adr     x1, msg_close
    mov     x2, #2
    mov     x8, #64
    svc     #0

print_max:
    // Imprimir mensaje del número mayor
    mov     x0, #1
    adr     x1, msg_max
    mov     x2, #35
    mov     x8, #64
    svc     #0
    
    // Convertir el máximo a string
    mov     w23, w10            // w23 = valor máximo
    sub     sp, sp, #16         // Reservar espacio en la pila
    mov     x22, sp             // x22 = dirección del buffer
    
    // Reutilizamos el mismo algoritmo de conversión
    mov     w24, w23            // w24 = número a convertir
    mov     x25, #0             // x25 = contador de dígitos (cambiado a x25)
    
convert_max_loop:
    mov     w26, #10
    udiv    w27, w24, w26       // w27 = w24 / 10
    msub    w28, w27, w26, w24  // w28 = w24 - (w27 * 10) = dígito
    
    add     w28, w28, #'0'      // Convertir a ASCII
    strb    w28, [x22, x25]     // Guardar en buffer (corregido a x25)
    add     x25, x25, #1        // Incrementar contador
    
    mov     w24, w27            // w24 = w24 / 10
    cbnz    w24, convert_max_loop
    
    // Invertir la cadena del máximo
    mov     x26, #0             // inicio (cambiado a x26)
    sub     x27, x25, #1        // fin (cambiado a x27)
    
reverse_max_loop:
    cmp     x26, x27
    b.ge    print_max_number
    
    ldrb    w28, [x22, x26]     // temp1 = str[inicio] (corregido a x26)
    ldrb    w29, [x22, x27]     // temp2 = str[fin] (corregido a x27)
    strb    w29, [x22, x26]     // str[inicio] = temp2 (corregido a x26)
    strb    w28, [x22, x27]     // str[fin] = temp1 (corregido a x27)
    
    add     x26, x26, #1        // inicio++
    sub     x27, x27, #1        // fin--
    b       reverse_max_loop
    
print_max_number:
    // Imprimir el número máximo
    mov     x0, #1
    mov     x1, x22
    mov     x2, x25
    mov     x8, #64
    svc     #0
    
    // Imprimir nueva línea
    mov     x0, #1
    adr     x1, newline
    mov     x2, #1
    mov     x8, #64
    svc     #0
    
    // Liberar buffer
    add     sp, sp, #16
    
exit:
    // Terminar programa
    mov     x0, #0      // código de salida 0
    mov     x8, #93     // syscall exit
    svc     #0