GNU/Linux xterm-256color bash 192 views

/*
Autor: Victor Manuel Madrid Lugo
Fecha: 08/04/2025
Descripción: Suma los elementos de un arreglo de 5 números enteros
Demostración: [https://asciinema.org/a/KsZaLEN9mdPU9hV70zmGTQeh3]

Equivalente en Fortran:
program suma_arreglo
  implicit none
  integer :: arreglo(5) = [10, 20, 30, 40, 50]
  integer :: suma, i
  
  suma = 0
  do i = 1, 5
    suma = suma + arreglo(i)
  end do
  
  print *, 'La suma del arreglo es: ', suma
end program suma_arreglo
*/

.section .data
    arreglo:    .word 10, 20, 30, 40, 50   // Arreglo de 5 números (4 bytes cada uno)
    msg_result: .asciz "La suma del arreglo es: "
    len_msg = . - msg_result - 1  // Longitud exacta del mensaje
    newline:    .asciz "\n"
    buffer:     .skip 12          // Buffer para conversión numérica

.section .text
.global _start

_start:
    // Inicializar variables
    mov x19, #0          // Contador (i)
    mov x20, #0          // Acumulador (suma)
    ldr x21, =arreglo    // Puntero al arreglo

suma_loop:
    // Cargar elemento actual (cada elemento son 4 bytes)
    ldr w22, [x21, x19, lsl #2]  // arreglo[i] = memoria[x21 + (x19 << 2)]

    // Sumar al acumulador
    add x20, x20, x22

    // Incrementar contador
    add x19, x19, #1

    // Verificar condición (i < 5)
    cmp x19, #5
    blt suma_loop

    // Convertir resultado a string
    ldr x0, =buffer
    mov x1, x20
    bl int_to_str
    mov x22, x0          // Guardar longitud del número

    // Imprimir mensaje
    mov x0, #1
    ldr x1, =msg_result
    mov x2, #len_msg     // Usar longitud calculada
    mov x8, #64          // syscall write
    svc #0

    // Imprimir resultado
    mov x0, #1
    ldr x1, =buffer
    mov x2, x22          // Usar longitud devuelta por int_to_str
    mov x8, #64
    svc #0

    // Imprimir nueva línea
    mov x0, #1
    ldr x1, =newline
    mov x2, #1
    mov x8, #64
    svc #0

    // Salir
    mov x0, #0
    mov x8, #93
    svc #0

// Función int_to_str mejorada
int_to_str:
    mov x2, #10
    mov x3, #0           // Contador dígitos
    mov x4, x0           // Guardar dirección buffer

    // Manejar 0
    cbz x1, handle_zero

    // Convertir dígitos
convert_loop:
    udiv x5, x1, x2      // x5 = x1 / 10
    msub x6, x5, x2, x1  // x6 = x1 % 10
    add x6, x6, #'0'
    strb w6, [x4, x3]
    add x3, x3, #1
    mov x1, x5
    cbnz x1, convert_loop

    // Invertir dígitos
    mov x5, #0           // inicio
    sub x6, x3, #1       // fin
reverse_loop:
    cmp x5, x6
    b.ge done
    ldrb w7, [x4, x5]
    ldrb w8, [x4, x6]
    strb w8, [x4, x5]
    strb w7, [x4, x6]
    add x5, x5, #1
    sub x6, x6, #1
    b reverse_loop

handle_zero:
    mov w5, #'0'
    strb w5, [x4]
    mov x3, #1

done:
    // Null terminator
    mov w5, #0
    strb w5, [x4, x3]
    mov x0, x3           // Devolver longitud
    ret