GNU/Linux xterm-256color bash 189 views

/*
Autor: Victor Manuel Madrid Lugo
Fecha: 09/04/2025
Descripción: Calcula el promedio de 3 números enteros
Demostración: [https://asciinema.org/a/uDkIXMT521l5ZvI7ruzezUZrP]

Equivalente en Java:
public class Promedio {
    public static void main(String[] args) {
        int num1 = 10, num2 = 20, num3 = 30;
        int suma = num1 + num2 + num3;
        int promedio = suma / 3;
        System.out.println("El promedio es: " + promedio);
    }
}
*/

.section .data
    num1:      .word 10       // Primer número
    num2:      .word 20       // Segundo número
    num3:      .word 30       // Tercer número
    msg_result: .asciz "El promedio es: "
    newline:    .asciz "\n"
    buffer:     .skip 12      // Buffer para conversión numérica

.section .text
.global _start

_start:
    // Cargar los 3 números
    ldr x19, =num1
    ldr w20, [x19]        // w20 = num1
    ldr x19, =num2
    ldr w21, [x19]        // w21 = num2
    ldr x19, =num3
    ldr w22, [x19]        // w22 = num3

    // Calcular suma (w23 = w20 + w21 + w22)
    add w23, w20, w21
    add w23, w23, w22

    // Calcular promedio (suma / 3)
    mov w24, #3
    sdiv w25, w23, w24    // w25 = w23 / 3 (división con signo)

    // Convertir resultado a string
    ldr x0, =buffer
    mov x1, x25
    bl int_to_str
    mov x26, x0           // Guardar longitud

    // Imprimir mensaje
    mov x0, #1
    ldr x1, =msg_result
    mov x2, #16           // Longitud de msg_result
    mov x8, #64           // syscall write
    svc #0

    // Imprimir promedio
    mov x0, #1
    ldr x1, =buffer
    mov x2, x26           // Longitud del número
    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 (conversión de entero a string)
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 reverse_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

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