GNU/Linux xterm bash 78 views

📌 Demostración: Suma de los elementos de un array en ARM64 Assembly

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

🎯 Descripción

Este programa suma los números que estén 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 suma_array.s -o suma_array.o  
ld suma_array.o -o suma_array 

▶️ Ejecución

./suma_array

👀 Código fuente

🔗 Código fuente en Gist: Programa 14 Suma de elementos de un array 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 suma los elementos                         | 
|   de un array en Rust y Assembly ARM64 para RaspbianOS.                | 
| • Demostración:                                                        |
|   https://asciinema.org/a/713351                                       |
| • Compilación (Raspberry Pi ARM64):                                    |  
|     as suma_array.s -o suma_array.o                                    |  
|     ld suma_array.o -o suma_array                                      |  
| • Ejecución: ./suma_array                                              |  
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄                                        

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

use std::io::{self, Write};

fn main() {
    let numbers = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
    let array_size = numbers.len();

    let sum: i32 = numbers.iter().sum();

    println!("La suma es: {}", sum);

    std::process::exit(0);
}

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

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

.global _start      // Punto de entrada global

.data
// Definimos un array de números
numbers:
    .word 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
array_size = 10

// Para imprimir el resultado
msg:
    .ascii "La suma es: "
msg_len = . - msg

newline:
    .ascii "\n"
newline_len = . - newline

// Búfer para convertir el resultado a caracteres ASCII
buffer:
    .skip 20         // Espacio reservado para dígitos ASCII

.text
_start:
    // Inicialización de registros
    mov x19, #0          // x19 = suma total
    mov x20, #0          // x20 = índice actual
    mov x21, #array_size // x21 = tamaño del array
    adr x22, numbers     // x22 = dirección del array

sum_loop:
    // Comprobar si hemos terminado
    cmp x20, x21
    b.ge print_result    // Si índice >= tamaño, salir del bucle

    // Cargar el valor actual del array y sumarlo
    ldr w23, [x22, x20, lsl #2]  // w23 = numbers[índice], multiplicado por 4 (tamaño de word)
    add x19, x19, x23            // suma += valor actual
    
    // Incrementar el índice
    add x20, x20, #1
    b sum_loop

print_result:
    // Imprimir mensaje "La suma es: "
    mov x0, #1              // File descriptor: 1 para stdout
    adr x1, msg             // Dirección del mensaje
    mov x2, #msg_len        // Longitud del mensaje
    mov x8, #64             // Syscall número 64: write
    svc #0                  // Llamada al sistema

    // Convertir el número a cadena ASCII
    mov x24, x19            // Copiar el resultado a x24
    adr x25, buffer         // x25 = puntero al fin del búfer
    add x25, x25, #19       // Empezar desde el final del búfer
    mov x26, #10            // x26 = base 10 para división

    // Manejar caso especial si el número es 0
    cbnz x24, convert_loop
    mov w27, '0'            // Carácter ASCII '0'
    strb w27, [x25]
    sub x25, x25, #1
    b end_convert

convert_loop:
    // Comprobar si el número es 0
    cbz x24, end_convert
    
    // Obtener el último dígito dividiendo por 10 y quedándonos con el resto
    udiv x27, x24, x26      // x27 = x24 / 10
    msub x28, x27, x26, x24 // x28 = x24 - (x27 * 10) = x24 % 10
    
    // Convertir dígito a ASCII y guardarlo
    add w28, w28, #'0'      // Convertir a carácter ASCII
    strb w28, [x25]         // Guardar en búfer
    sub x25, x25, #1        // Mover puntero
    
    // Actualizar número para siguiente iteración
    mov x24, x27            // Número = número / 10
    b convert_loop

end_convert:
    // Calcular longitud de la cadena resultante
    add x25, x25, #1        // Ajustar puntero al primer dígito
    adr x24, buffer
    add x24, x24, #20
    sub x2, x24, x25        // x2 = longitud de la cadena
    
    // Imprimir número
    mov x0, #1              // File descriptor: 1 para stdout
    mov x1, x25             // Dirección del búfer
    mov x8, #64             // Syscall número 64: write
    svc #0                  // Llamada al sistema
    
    // Imprimir nueva línea
    mov x0, #1              // File descriptor: 1 para stdout
    adr x1, newline         // Dirección del mensaje
    mov x2, #newline_len    // Longitud del mensaje
    mov x8, #64             // Syscall número 64: write
    svc #0                  // Llamada al sistema

    // Salir del programa
    mov x0, #0              // Código de salida: 0 (éxito)
    mov x8, #93             // Syscall número 93: exit
    svc #0                  // Llamada al sistema