GNU/Linux xterm-256color bash 135 views

// ****************************************************************************
// * Lenguajes de Interfaz en TECNM Campus ITT
// * Nombre del archivo: vocales.s
// * Descripción:  Programa que cuenta cuantas vocales hay en una cadena
// * Autor: [America Fernanda Nevarez de la Cruz]
// * Fecha: [2025-04-07]
// * Plataforma: Raspberry Pi OS (64 bits)
// * Demostración:  [https://asciinema.org/a/0qr1xTXxdMRgSSF6i4vrZQFh1]
// ****************************************************************************

// ****************************************************************************
// * Codigo equivalente en Javascript
// * function contarVocales() {
// * const cadena = prompt("Ingrese una cadena: ");
// * if (!cadena) return;
// * let contador = 0;
// * const cadenaMin = cadena.toLowerCase();
// * for (let i = 0; i < cadenaMin.length; i++) {
// *        const caracter = cadenaMin[i];
// *        if (caracter === 'a' || caracter === 'e' || caracter === 'i' || 
// *            caracter === 'o' || caracter === 'u') {
// *            contador++;
// *        }
// *    }
// * alert(`Cantidad de vocales: ${contador}`);
// * }
// * contarVocales();
// ****************************************************************************
.section .bss
input_buffer: .skip 64

.section .data
msg_pedir: .ascii "Ingrese una cadena: "
len_pedir = . - msg_pedir

msg_resultado: .ascii "Cantidad de vocales: "
len_resultado = . - msg_resultado

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

.section .text
.global _start

_start:
    // Mostrar mensaje
    ldr x0, =msg_pedir
    mov x1, #len_pedir
    bl print_msg

    // Leer entrada
    mov x0, #0                  // stdin
    ldr x1, =input_buffer
    mov x2, #64                 // hasta 64 bytes
    mov x8, #63                 // syscall read
    svc #0

    // x0 contiene cantidad de bytes leídos
    // x1 apunta a input_buffer
    ldr x1, =input_buffer
    mov x2, x0                  // número de bytes leídos
    mov x3, #0                  // contador de vocales

check_loop:
    cbz x2, done_check          // si terminamos, salimos

    ldrb w4, [x1], #1           // leer siguiente byte
    sub x2, x2, #1              // reducir bytes restantes

    // Comparar contra vocales minúsculas
    cmp w4, #'a'
    beq inc_count
    cmp w4, #'e'
    beq inc_count
    cmp w4, #'i'
    beq inc_count
    cmp w4, #'o'
    beq inc_count
    cmp w4, #'u'
    beq inc_count

    // Comparar contra vocales mayúsculas
    cmp w4, #'A'
    beq inc_count
    cmp w4, #'E'
    beq inc_count
    cmp w4, #'I'
    beq inc_count
    cmp w4, #'O'
    beq inc_count
    cmp w4, #'U'
    beq inc_count

    b check_loop

inc_count:
    add x3, x3, #1
    b check_loop

done_check:
    // Mostrar mensaje
    ldr x0, =msg_resultado
    mov x1, #len_resultado
    bl print_msg

    // Mostrar número de vocales (x3)
    mov x0, x3
    bl print_number

    // Imprimir salto de línea
    ldr x0, =newline
    mov x1, #len_nl
    bl print_msg

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

// Función: print_msg
print_msg:
    mov x2, x1     // longitud
    mov x1, x0     // puntero al mensaje
    mov x0, #1     // stdout
    mov x8, #64
    svc #0
    ret

// Función: print_number
print_number:
    // x0: número a imprimir
    mov x1, x0
    ldr x2, =input_buffer
    add x2, x2, #63     // escribir desde el final del buffer hacia atrás
    mov w3, #0

convert_loop:
    mov x4, #10
    udiv x5, x1, x4
    msub x6, x5, x4, x1 // x6 = x1 - x5 * 10
    add x6, x6, #'0'
    strb w6, [x2], #-1
    mov x1, x5
    add w3, w3, #1
    cbnz x1, convert_loop

    add x2, x2, #1
    mov x1, x2
    mov w2, w3
    mov x0, #1
    mov x8, #64
    svc #0
    ret