// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Contar la cantidad de caracteres de una cadena
// * Autor: Roldan Castro Luis Alberto
// * Fecha: 07-04-2025
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/jZUN6lI7v1EVBrLAnoTxHH9SS
// ****************************************************************************
// ****************************************************************************
// * Codigo equivalente en python
// * import sys
// *
// * def print_number(num):
// * """Función equivalente a print_number en ensamblador"""
// * return str(num) # Python convierte automáticamente números a strings
// *
// * def main():
// * input_str = sys.stdin.readline() # Equivalente a syscall read
// * length = len(input_str)
// * if input_str.endswith('\n'):
// * input_str = input_str[:-1] # Eliminar último carácter
// * length -= 1
// * sys.stdout.write("Longitud: ")
// * num_str = print_number(length)
// * sys.stdout.write(num_str)
// * sys.stdout.write("\n")
// * if _name_ == "_main_":
// * main()
// ****************************************************************************
.global _start
.section .bss
input_buffer: .skip 128 // Buffer para la cadena
number_buffer: .skip 16 // Buffer para el número en texto
.section .text
_start:
// ======================
// Leer cadena desde stdin
// ======================
MOV X0, #0 // stdin
ADR X1, input_buffer // buffer destino
MOV X2, #128 // tamaño máx
MOV X8, #63 // syscall: read
SVC #0
MOV X20, X0 // Guardar longitud original
// ======================
// Eliminar el salto de línea (\n)
// ======================
ADR X1, input_buffer
ADD X1, X1, X20 // apunta al final
SUB X1, X1, #1 // retrocede 1
LDRB W2, [X1]
CMP W2, #10 // comparar con '\n'
BNE skip_trim
SUB X20, X20, #1 // descontar \n
skip_trim:
// ======================
// Mostrar mensaje: "Longitud: "
// ======================
LDR X1, =msg
MOV X2, #10 // longitud del mensaje
MOV X0, #1 // stdout
MOV X8, #64 // syscall: write
SVC #0
// ======================
// Convertir número (X20) a ASCII
// ======================
MOV X6, X20 // número a convertir
BL print_number // convierte y lo imprime
// Salto de línea
LDR X1, =newline
MOV X2, #1
MOV X0, #1
MOV X8, #64
SVC #0
// ======================
// Salida limpia
// ======================
MOV X0, #0
MOV X8, #93 // syscall: exit
SVC #0
// ========================================
// Función: print_number
// Entrada: X6 = número
// Usa: number_buffer para la conversión
// ========================================
print_number:
ADR X7, number_buffer
ADD X7, X7, #15 // apuntamos al final
MOV X8, X6 // copia del número
MOV X9, #0 // contador de dígitos
print_loop:
MOV X10, #10
UDIV X11, X8, X10 // cociente
MUL X12, X11, X10
SUB X13, X8, X12 // resto
ADD X13, X13, #'0' // convertir a ASCII
STRB W13, [X7], #-1 // guardar y retroceder
MOV X8, X11
ADD X9, X9, #1
CBNZ X8, print_loop
// Imprimir número
ADD X1, X7, #1 // buffer corregido
MOV X2, X9 // longitud
MOV X0, #1
MOV X8, #64
SVC #0
RET
.section .rodata
msg: .asciz "Longitud: "
newline: .asciz "\n"