GNU/Linux xterm-256color bash 139 views

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