GNU/Linux xterm-256color bash 203 views

/*
Autor: Victor Manuel Madrid Lugo
Fecha: 09/04/2025
Descripción: Cuenta letras minúsculas en una cadena ingresada
Demostración: [https://asciinema.org/a/GhR5gOITXGJZAXc6Isz1ZZWdc]

Equivalente en Java:
import java.util.Scanner;

public class ContarMinusculas {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Ingrese una cadena: ");
        String texto = sc.nextLine();
        int contador = 0;
        
        for (int i = 0; i < texto.length(); i++) {
            char c = texto.charAt(i);
            if (c >= 'a' && c <= 'z') {
                contador++;
            }
        }
        System.out.println("Total de minúsculas: " + contador);
    }
}
*/

.section .data
    msg_prompt:    .asciz "Ingrese una cadena: "
    msg_result:    .asciz "Total de minúsculas: "
    newline:       .asciz "\n"
    buffer:        .skip 256      // Buffer para la cadena
    num_buffer:    .skip 12       // Buffer para el número

.section .text
.global _start

_start:
    // Mostrar mensaje
    mov x0, #1
    ldr x1, =msg_prompt
    mov x2, #19          // Longitud de msg_prompt
    mov x8, #64          // syscall write
    svc #0

    // Leer cadena
    mov x0, #0
    ldr x1, =buffer
    mov x2, #256         // Tamaño máximo
    mov x8, #63          // syscall read
    svc #0

    // Inicializar contador
    mov x19, #0          // Contador de minúsculas
    mov x20, #0          // Índice
    ldr x21, =buffer     // Puntero al buffer

count_loop:
    // Cargar carácter actual
    ldrb w22, [x21, x20]
    cbz w22, end_count   // Fin si es null
    cmp w22, #10         // Fin si es newline
    beq end_count

    // Verificar si es minúscula (a-z)
    cmp w22, #'a'
    blt next_char
    cmp w22, #'z'
    bgt next_char

    // Incrementar contador si es minúscula
    add x19, x19, #1

next_char:
    add x20, x20, #1     // Siguiente carácter
    b count_loop

end_count:
    // Convertir contador a string
    ldr x0, =num_buffer
    mov x1, x19
    bl int_to_str
    mov x23, x0          // Guardar longitud

    // Mostrar resultado
    mov x0, #1
    ldr x1, =msg_result
    mov x2, #21          // Longitud de msg_result
    mov x8, #64
    svc #0

    mov x0, #1
    ldr x1, =num_buffer
    mov x2, x23          // Longitud del número
    mov x8, #64
    svc #0

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

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