GNU/Linux xterm-256color bash 186 views

// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Programa que detecta la cantidad de "A" de una cadena y las cuenta
// * Autor: Roldan Castro Luis Alberto
// * Fecha:08-04-2025 
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/JfFxfyP2pdldLWVZwUnmiCaom
// ****************************************************************************

// ****************************************************************************
//Version en python
//
//def contar_a(cadena):
//    return cadena.upper().count("A")
//
//# Ejemplo de uso
//texto = input("Ingrese una cadena de texto: ")
//cantidad_a = contar_a(texto)
//print(f"La cantidad de 'A' en la cadena es: {cantidad_a}")
// ****************************************************************************

.section .bss
input_buffer: .skip 64      // Buffer de entrada del usuario (64 bytes)
number_buffer: .skip 16     // Buffer para almacenar número convertido a texto

.section .data
msg_pedir: .ascii "Ingrese una cadena: "   // Mensaje para solicitar entrada
len_pedir = . - msg_pedir                  // Longitud del mensaje

msg_resultado: .ascii "Cantidad de letras A: "  // Mensaje para mostrar resultado
len_resultado = . - msg_resultado

newline: .ascii "\n"       // Salto de línea
len_nl = . - newline       // Longitud del salto

.section .text
.global _start

_start:
    // Mostrar mensaje para pedir entrada
    ldr x0, =msg_pedir         // Dirección del mensaje
    mov x1, #len_pedir         // Longitud del mensaje
    bl print_msg               // Llamar a función para imprimir mensaje

    // Leer entrada del usuario
    mov x0, #0                 // stdin (entrada estándar)
    ldr x1, =input_buffer      // Dirección del buffer de entrada
    mov x2, #64                // Tamaño máximo a leer
    mov x8, #63                // syscall: read
    svc #0                     // Llamada al sistema

    // Preparar registros para contar letras A/a
    ldr x1, =input_buffer      // Dirección inicial del buffer
    mov x2, x0                 // Longitud real de la entrada leída
    mov x3, #0                 // Contador de letras A/a en cero

check_loop:
    cbz x2, done_check         // Si ya no quedan caracteres, salir del bucle

    ldrb w4, [x1], #1          // Leer siguiente byte y avanzar
    sub x2, x2, #1             // Decrementar longitud restante

    cmp w4, #'a'               // Comparar con letra 'a'
    beq inc_count              // Si es igual, incrementar contador
    cmp w4, #'A'               // Comparar con letra 'A'
    beq inc_count              // Si es igual, incrementar contador
    b check_loop               // Continuar con el siguiente carácter

inc_count:
    add x3, x3, #1             // Incrementar contador
    b check_loop               // Continuar escaneo

done_check:
    // Mostrar mensaje del resultado
    ldr x0, =msg_resultado     // Dirección del mensaje
    mov x1, #len_resultado     // Longitud del mensaje
    bl print_msg               // Imprimir mensaje

    // Mostrar número (contador en x3)
    mov x0, x3                 // Pasar número a imprimir
    bl print_number            // Llamar función para imprimir número

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

    // Salir del programa
    mov x8, #93                // syscall: exit
    mov x0, #0                 // Código de salida 0
    svc #0

// -------------------------------------------
// Función print_msg
// x0 = dirección del mensaje, x1 = longitud
print_msg:
    mov x2, x1                 // Longitud
    mov x1, x0                 // Dirección
    mov x0, #1                 // stdout
    mov x8, #64                // syscall: write
    svc #0
    ret

// -------------------------------------------
// Función print_number
// x0 = número a imprimir
print_number:
    mov x1, x0                 // Copiar número
    ldr x2, =number_buffer     // Cargar dirección del buffer
    add x2, x2, #15            // Apuntar al final del buffer
    mov w3, #0                 // Contador de dígitos

convert_loop:
    mov x4, #10
    udiv x5, x1, x4            // x5 = x1 / 10
    msub x6, x5, x4, x1        // x6 = x1 - (x5 * 10) = resto
    add x6, x6, #'0'           // Convertir dígito a ASCII
    strb w6, [x2], #-1         // Guardar byte y retroceder puntero
    mov x1, x5                 // Actualizar valor para siguiente ciclo
    add w3, w3, #1             // Incrementar cantidad de dígitos
    cbnz x1, convert_loop      // Repetir mientras número > 0

    add x2, x2, #1             // Apuntar al primer carácter válido
    mov x1, x2                 // Dirección de inicio
    mov w2, w3                 // Longitud del número
    mov x0, #1                 // stdout
    mov x8, #64                // syscall: write
    svc #0
    ret