GNU/Linux
•
xterm
•
bash
165 views
Este código en ensamblador ARM64 tiene como objetivo leer una cadena de caracteres desde la entrada estándar, contar el número de vocales y consonantes en la cadena y luego imprimir los resultados. A continuación, te explico el código detalladamente:
Sección de Datos (.data):
-
msg_ingreso: Mensaje que se muestra al usuario pidiendo que ingrese una cadena de texto. -
msg_vocales: Mensaje que se imprimirá mostrando el número de vocales. -
msg_consonantes: Mensaje que se imprimirá mostrando el número de consonantes. -
buffer: Un espacio de 100 bytes en memoria para almacenar la cadena ingresada por el usuario. -
formato_str: Especifica el formato para leer una cadena de caracteres hasta que se encuentre un salto de línea (\n). -
vocales: Cadena que contiene las vocales tanto en minúsculas como en mayúsculas (para poder comparar caracteres con ambas formas).
Sección de Código (.text):
La ejecución comienza en la función main.
1. Prologo (Preparación de la pila):
stp x29, x30, [sp, -32]! // Guardar el puntero de marco (x29) y el enlace de retorno (x30) en la pila
mov x29, sp // Establecer el puntero de marco
-
stp x29, x30, [sp, -32]!: Guarda los registrosx29(puntero de marco) yx30(registro de enlace de retorno) en la pila. -
mov x29, sp: Establece el puntero de marco al valor actual del puntero de pila (sp), que se usa para gestionar el contexto de la función.
2. Inicialización de los contadores:
str xzr, [sp, 16] // Inicializar contador de vocales en 0 (xzr es el registro que contiene 0)
str xzr, [sp, 24] // Inicializar contador de consonantes en 0
-
str xzr, [sp, 16]: Guarda el valor 0 en la direcciónsp + 16, que es el contador de vocales. -
str xzr, [sp, 24]: Guarda el valor 0 en la direcciónsp + 24, que es el contador de consonantes.
3. Mostrar mensaje de ingreso y leer la cadena:
adr x0, msg_ingreso // Cargar la dirección del mensaje de ingreso
bl printf // Llamar a printf para mostrar el mensaje
adr x0, formato_str // Cargar el formato para leer una cadena
adr x1, buffer // Dirección de memoria donde se almacenará la cadena
bl scanf // Llamar a scanf para leer la cadena
-
adr x0, msg_ingreso: Carga la dirección del mensaje “Ingrese una cadena” enx0para que sea usado porprintf. -
bl printf: Llama aprintfpara imprimir el mensaje de ingreso. -
adr x0, formato_str: Carga el formato para leer una cadena (usando%[^\n]para leer hasta el salto de línea). -
adr x1, buffer: Carga la dirección delbufferdonde se almacenará la cadena ingresada. -
bl scanf: Llama ascanfpara leer la cadena de caracteres del usuario.
4. Procesar cada carácter de la cadena:
El ciclo principal procesar_char recorre cada carácter de la cadena ingresada y realiza el conteo de vocales y consonantes.
procesar_char:
ldrb w2, [x0, x1] // Cargar el carácter en w2
cbz w2, fin_conteo // Si es 0 (fin de la cadena), salimos del ciclo
// Verificar si el carácter es una letra
cmp w2, #'A'
b.lt siguiente_char
cmp w2, #'z'
b.gt siguiente_char
cmp w2, #'Z'
b.le es_letra
cmp w2, #'a'
b.ge es_letra
b siguiente_char
-
ldrb w2, [x0, x1]: Carga el carácter de la cadena en el registrow2(un byte). -
cbz w2, fin_conteo: Si el valor dew2es 0 (fin de la cadena), salta afin_conteopara terminar el procesamiento. -
cmp w2, #'A': Compara el carácter con'A'(mayúsculas). -
b.lt siguiente_char: Si el carácter es menor que'A', no es una letra, por lo que se salta al siguiente carácter. -
cmp w2, #'z': Compara con'z'(minúsculas). -
b.gt siguiente_char: Si el carácter es mayor que'z', no es una letra y se pasa al siguiente. -
cmp w2, #'Z': Compara con'Z'(mayúsculas). -
b.le es_letra: Si el carácter está entre'A'y'Z', es una letra. -
cmp w2, #'a': Compara con'a'(minúsculas). -
b.ge es_letra: Si el carácter está entre'a'y'z', es una letra.
5. Verificar si la letra es una vocal:
es_letra:
adr x3, vocales // Cargar la dirección de la cadena de vocales
mov x4, #0 // Iniciar el índice de vocales en 0
check_vocal:
ldrb w5, [x3, x4] // Cargar una vocal
cbz w5, es_consonante // Si llegamos al final de la cadena de vocales, es consonante
cmp w2, w5 // Comparar el carácter con la vocal
b.eq es_vocal // Si es igual, es una vocal
add x4, x4, #1 // Incrementar el índice
b check_vocal // Continuar verificando con la siguiente vocal
-
adr x3, vocales: Carga la dirección de la cadena de vocales. -
mov x4, #0: Inicializa el índicex4a 0 para recorrer las vocales. -
ldrb w5, [x3, x4]: Carga una vocal de la cadena de vocales enw5. -
cbz w5, es_consonante: Siw5es 0 (llegamos al final de la cadena de vocales), salta aes_consonante. -
cmp w2, w5: Compara el carácter actual con la vocal. -
b.eq es_vocal: Si es una vocal, salta aes_vocal. -
add x4, x4, #1: Incrementa el índicex4y continúa con la siguiente vocal.
6. Incrementar el contador de vocales o consonantes:
es_vocal:
ldr x4, [sp, 16] // Cargar contador de vocales
add x4, x4, #1 // Incrementar el contador
str x4, [sp, 16] // Guardar el nuevo contador
b siguiente_char
es_consonante:
ldr x4, [sp, 24] // Cargar contador de consonantes
add x4, x4, #1 // Incrementar el contador
str x4, [sp, 24] // Guardar el nuevo contador
- Si el carácter es una vocal, se incrementa el contador de vocales. Si no es una vocal, se incrementa el contador de consonantes.
7. Mostrar los resultados:
fin_conteo:
adr x0, msg_vocales // Cargar mensaje de vocales
ldr x1, [sp, 16] // Cargar el número de vocales
bl printf // Imprimir número de vocales
adr x0, msg_consonantes // Cargar mensaje de consonantes
ldr x1, [sp, 24] // Cargar el número de consonantes
bl printf // Imprimir número de consonantes
-
Al finalizar el procesamiento, el programa imprime los resultados de las vocales y consonantes usando
printf.
8. Epílogo (Restaurar la pila y retornar):
mov w0, #0 // Establecer el valor de retorno a 0
ldp x29, x30, [sp], 32 // Restaurar los registros x29 y x30 desde la pila
ret // Retornar al sistema operativo
-
mov w0, #0: Establece el valor de retorno a 0. -
ldp x29, x30, [sp], 32: Restaura el puntero de marco y el enlace de retorno desde la pila. -
ret: Finaliza el programa y retorna al sistema operativo.
Resumen:
Este programa en ensamblador ARM64:
- Solicita al usuario que ingrese una cadena de texto.
- Recorre cada carácter de la cadena, contando las vocales y consonantes.
- Imprime el número de vocales y consonantes en la cadena.
Es un ejemplo interesante de cómo manejar cadenas de texto y realizar comparaciones y manipulaciones en ensamblador ARM64.