GNU/Linux xterm-256color bash 189 views

/*
Autor: Victor Manuel Madrid Lugo
Fecha: 09/04/2025
Descripción: Resta los elementos de un arreglo de 5 números enteros (arreglo[0] - arreglo[1] - ... - arreglo[4])
Demostración: [https://asciinema.org/a/hutPI3P3tmQf3XvYoOWlb2Jlw]

Equivalente en C:
int arreglo[5] = {100, 20, 30, 10, 5};
int resta = arreglo[0];
for(int i = 1; i < 5; i++) {
    resta -= arreglo[i];
}
printf("La resta del arreglo es: %d\n", resta);
*/

.section .data
    arreglo:    .word 100, 20, 30, 10, 5   // Arreglo de 5 números (4 bytes cada uno)
    msg_result: .asciz "La resta 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)
    ldr x20, =arreglo    // Puntero al arreglo
    
    // Cargar primer elemento (arreglo[0])
    ldr w21, [x20, x19, lsl #2]  // resta = arreglo[0]
    add x19, x19, #1     // i = 1

resta_loop:
    // Verificar condición (i < 5)
    cmp x19, #5
    bge print_result
    
    // Restar elemento actual (resta -= arreglo[i])
    ldr w22, [x20, x19, lsl #2]  // Cargar arreglo[i]
    sub w21, w21, w22    // resta = resta - arreglo[i]
    
    // Incrementar contador
    add x19, x19, #1
    b resta_loop

print_result:
    // Convertir resultado a string
    ldr x0, =buffer
    mov x1, x21
    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 (igual que en ejemplos anteriores)
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

    // Manejar negativos
    cmp x1, #0
    b.gt positive
    neg x1, x1
    mov w5, #'-'
    strb w5, [x4], #1
    add x3, x3, #1

positive:
    // 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