GNU/Linux xterm-256color zsh 166 views

//========================================================================= // Nombre del estudiante: Vargas Perez Leonardo Gael // Fecha de creación: 2025-04-09 // Descripción: Programa que cuenta las ocurrencias de una letra en una cadena // Link asciinema: [https://asciinema.org/a/4ftk4GL6utyBtPXdtYohod6rB] //========================================================================= // Versión alternativa en Python: // python // cadena = input("Ingrese una cadena: ") // letra = input("Ingrese la letra a buscar: ") // if len(letra) != 1: // print("Error: Debe ingresar exactamente un carácter") // else: // print(f"La letra '{letra}' aparece {cadena.count(letra)} veces") // //=========================================================================

.section .data

// Mensajes para el usuario
prompt_str:    .asciz "Ingrese una cadena: "
prompt_char:   .asciz "Ingrese la letra a buscar: "
result_msg1:   .asciz "La letra '"
result_msg2:   .asciz "' aparece "
result_msg3:   .asciz " veces.\n"
error_msg:     .asciz "Error: Debe ingresar exactamente un carácter.\n"
newline:       .asciz "\n"

.section .bss

// Buffers para entrada/salida
input_str:     .skip 256      // Buffer para la cadena (255 caracteres + null)
input_char:    .skip 4        // Buffer para el carácter (1 char + \n + null)
count_str:     .skip 21       // Buffer para el contador como string

.section .text .global _start

_start:

// ----- Fase 1: Leer entrada del usuario -----
// Solicitar cadena principal
ldr x0, =prompt_str
bl print_string
ldr x0, =input_str
mov x1, #256
bl read_input

// Solicitar carácter a buscar
ldr x0, =prompt_char
bl print_string
ldr x0, =input_char
mov x1, #4
bl read_input

// ----- Fase 2: Validar entrada -----
// Verificar que se ingresó exactamente 1 carácter
ldr x0, =input_char
ldrb w1, [x0, #1]          // Segundo byte
cbz w1, valid_input        // Null terminator es válido
cmp w1, #10                // Newline también es válido
beq valid_input
b invalid_input            // Cualquier otra cosa es error

valid_input:

// ----- Fase 3: Procesamiento -----
// Cargar carácter a buscar
ldr x0, =input_char
ldrb w19, [x0]             // w19 = carácter a buscar (byte)

// Contar ocurrencias en la cadena
ldr x0, =input_str
mov w1, w19
bl count_occurrences
mov x20, x0                // x20 = contador de ocurrencias

// ----- Fase 4: Mostrar resultados -----
// Construir mensaje de resultado
ldr x0, =result_msg1
bl print_string

// Imprimir el carácter buscado (seguro usando stack)
sub sp, sp, #16            // Reservar espacio en stack
strb w19, [sp, #8]         // Almacenar carácter
mov x0, #1                 // stdout
add x1, sp, #8             // Dirección del carácter
mov x2, #1                 // Longitud 1 byte
mov x8, #64                // syscall write
svc #0
add sp, sp, #16            // Liberar stack

ldr x0, =result_msg2
bl print_string

// Convertir y mostrar el contador
mov x0, x20
ldr x1, =count_str
bl int_to_string
ldr x0, =count_str
bl print_string

ldr x0, =result_msg3
bl print_string

b exit

invalid_input:

ldr x0, =error_msg
bl print_string

exit:

// Terminar programa exitosamente
mov x0, #0                 // Código de retorno 0
mov x8, #93                // syscall exit
svc #0

// ==================== SUBRUTINAS ====================

//—————————————————– // count_occurrences - Cuenta apariciones de un carácter // Entrada: x0 = dirección de la cadena // w1 = carácter a buscar (byte) // Salida: x0 = número de ocurrencias //—————————————————– count_occurrences:

mov x2, #0                 // Inicializar contador

count_loop:

ldrb w3, [x0], #1          // Cargar byte y avanzar puntero
cbz w3, count_done         // Terminar al llegar a null

cmp w3, w1                 // Comparar con el carácter buscado
bne count_loop             // Si no coincide, continuar

add x2, x2, #1             // Incrementar contador
b count_loop

count_done:

mov x0, x2                 // Devolver resultado
ret

//—————————————————– // print_string - Imprime una cadena terminada en null // Entrada: x0 = dirección de la cadena //—————————————————– print_string:

mov x1, x0                 // Guardar dirección
mov x2, #0                 // Inicializar contador de longitud

str_len_loop:

ldrb w3, [x1, x2]          // Cargar byte actual
cbz w3, str_print          // Si es null, terminar
add x2, x2, #1             // Incrementar contador
b str_len_loop

str_print:

mov x1, x0                 // Dirección de la cadena
mov x0, #1                 // stdout
mov x8, #64                // syscall write
svc #0
ret

//—————————————————– // read_input - Lee entrada del usuario // Entrada: x0 = buffer de destino // x1 = tamaño máximo del buffer //—————————————————– read_input:

mov x2, x1                 // Tamaño máximo
mov x1, x0                 // Buffer de destino
mov x0, #0                 // stdin
mov x8, #63                // syscall read
svc #0
ret

//—————————————————– // int_to_string - Convierte entero a string // Entrada: x0 = número a convertir // x1 = buffer de destino //—————————————————– int_to_string:

mov x2, x1                 // Guardar buffer destino
mov x3, #10                // Base 10
mov x4, #0                 // Contador de dígitos

// Caso especial para 0
cbz x0, handle_zero

conversion_loop:

udiv x5, x0, x3            // Dividir por 10
msub x6, x5, x3, x0        // Obtener residuo
add x6, x6, #'0'           // Convertir a ASCII
strb w6, [x1, x4]          // Almacenar dígito
add x4, x4, #1             // Incrementar contador
mov x0, x5                 // Actualizar número
cbnz x0, conversion_loop   // Continuar si no es cero

// Terminar cadena
mov w5, #0
strb w5, [x1, x4]

// Invertir los dígitos
mov x5, #0                 // Índice inicial
sub x6, x4, #1             // Índice final

reverse_loop:

cmp x5, x6
bge conversion_done
ldrb w7, [x1, x5]          // Intercambiar
ldrb w8, [x1, x6]          // caracteres
strb w8, [x1, x5]
strb w7, [x1, x6]
add x5, x5, #1
sub x6, x6, #1
b reverse_loop

handle_zero:

mov w5, #'0'
strb w5, [x1]
mov w5, #0
strb w5, [x1, #1]

conversion_done:

ret

// Fin del programa