GNU/Linux xterm-256color bash 190 views

// ****************************************************************************
// * Nombre del archivo: practica.s
// * Descripción: Programa que convierte un numero decimala base 20
// * Autor: Roldan Castro Luis Alberto
// * Fecha: 08-04-2025
// * Plataforma: Raspberry Pi OS (64 bits)
// * Asciinema: https://asciinema.org/a/XL4iORQwrgSyy9hPHm32iiR1n
// ****************************************************************************

// ****************************************************************************
//Version en Swift
//
//import Foundation
//
//func decimalToString(_ number: Int) -> String {
//    return String(number)
//}
//
//func decimalToBase20(_ number: Int) -> String {
//    let digits = Array("0123456789ABCDEFGHIJ")
//    var result = ""
//    var num = number
//    
//    repeat {
//        let remainder = num % 20
//        result = String(digits[remainder]) + result
//        num /= 20
//    } while num > 0
//    
//    return result
//}
//
//func main() {
//    let number = 500  // Número a convertir
//    
//    // Mostrar "Decimal "
//    print("Decimal", terminator: " ")
//    
//    // Mostrar el número decimal
//    print(decimalToString(number), terminator: "")
//    
//    // Mostrar " en base 20 es: "
//    print(" en base 20 es:", terminator: " ")
//    
//    // Mostrar el número en base 20
//    print(decimalToBase20(number))
//}
//
//main()
//
// ****************************************************************************

.global _start         // Punto de entrada del programa

.section .bss          // Sección de memoria no inicializada (buffers)
base20_buffer: .skip 32     // Buffer para almacenar el número convertido a base 20
dec_buffer:     .skip 16     // Buffer para almacenar el número decimal como texto

.section .text         // Sección de código

_start:
    // ========================
    // Inicializar número a convertir
    // ========================
    MOV X6, #500             // Número decimal que queremos convertir (antes era 324)
    MOV X20, X6              // Guardamos una copia del número original en X20

    // ========================
    // Mostrar mensaje "Decimal "
    // ========================
    LDR X1, =msg1            // Cargamos dirección del mensaje "Decimal "
    MOV X2, #8               // Longitud del mensaje
    MOV X0, #1               // Salida estándar (pantalla)
    MOV X8, #64              // syscall write
    SVC #0                   // Llamada al sistema

    // ========================
    // Mostrar el número decimal
    // ========================
    MOV X6, X20              // Restauramos el número a convertir
    BL print_decimal         // Llamamos a función que imprime en decimal

    // ========================
    // Mostrar mensaje " en base 20 es: "
    // ========================
    LDR X1, =msg2            // Dirección del mensaje
    MOV X2, #20              // Longitud del mensaje
    MOV X0, #1               // Salida estándar
    MOV X8, #64              // syscall write
    SVC #0

    // ========================
    // Mostrar número en base 20
    // ========================
    MOV X6, X20              // Restauramos el número a convertir
    BL print_base20          // Llamamos a función que convierte e imprime en base 20

    // ========================
    // Salto de línea final
    // ========================
    LDR X1, =newline         // Dirección del salto de línea
    MOV X2, #1               // Longitud de un carácter
    MOV X0, #1
    MOV X8, #64
    SVC #0

    // ========================
    // Salida limpia del programa
    // ========================
    MOV X0, #0               // Código de salida
    MOV X8, #93              // syscall exit
    SVC #0

// ========================
// Función: print_decimal (imprime número en base 10)
// Entrada: X6 (número a imprimir)
// ========================
print_decimal:
    ADR X7, dec_buffer       // Apuntamos al buffer decimal
    ADD X7, X7, #15          // Nos movemos al final del buffer
    MOV X8, X6               // Copia del número
    MOV X9, #0               // Contador de dígitos

dec_loop:
    MOV X10, #10             // Base 10
    UDIV X11, X8, X10        // X11 = X8 / 10
    MUL X12, X11, X10        // X12 = (X8 / 10) * 10
    SUB X13, X8, X12         // X13 = dígito actual (X8 % 10)
    ADD X13, X13, #'0'       // Convertimos dígito a carácter ASCII
    STRB W13, [X7], #-1      // Almacenamos en buffer y retrocedemos
    MOV X8, X11              // Siguiente número
    ADD X9, X9, #1           // Incrementamos contador
    CBNZ X8, dec_loop        // Si aún no llegamos a cero, repetir

    ADD X1, X7, #1           // Ajustamos dirección de inicio
    MOV X2, X9               // Longitud del número
    MOV X0, #1
    MOV X8, #64
    SVC #0
    RET

// ========================
// Función: print_base20 (convierte e imprime en base 20)
// Entrada: X6 (número a convertir)
// ========================
print_base20:
    ADR X7, base20_buffer    // Apuntamos al buffer de base 20
    ADD X7, X7, #31          // Vamos al final del buffer
    MOV X8, X6               // Copia del número
    MOV X9, #0               // Contador

base20_loop:
    MOV X10, #20             // Base 20
    UDIV X11, X8, X10        // División entera por 20
    MUL X12, X11, X10        // Multiplicamos para restar
    SUB X13, X8, X12         // Residuo (dígito actual)

    // Si el dígito > 9, usamos letras A-J
    CMP X13, #9
    BLE store_base20_digit   // Si ≤ 9, convertir a dígito
    ADD X13, X13, #'A' - 10  // Convertir a letra (10 = A, 11 = B, ...)
    B store_base20

store_base20_digit:
    ADD X13, X13, #'0'       // Convertir a carácter ASCII numérico

store_base20:
    STRB W13, [X7], #-1      // Guardamos el carácter
    MOV X8, X11              // Continuamos con el cociente
    ADD X9, X9, #1           // Incrementamos contador
    CBNZ X8, base20_loop     // Repetimos si el número no es cero

    ADD X1, X7, #1           // Ajustamos dirección del resultado
    MOV X2, X9               // Longitud del resultado
    MOV X0, #1
    MOV X8, #64
    SVC #0
    RET

// ========================
// Sección de datos constantes
// ========================
.section .rodata
msg1:    .asciz "Decimal "           // Texto fijo
msg2:    .asciz " en base 20 es: "   // Texto fijo
newline: .asciz "\n"                 // Salto de línea