GNU/Linux xterm-256color bash 146 views

//==================================================
// Autor: Victor Manuel Madrid Lugo
// Fecha: 07/04/2025
// Descripción: itoa - conversión de numero en base decimal a hexadecimal
// SO: Raspberry Pi OS 64-bit
// Demostración: [https://asciinema.org/a/74JkCuNtl7sWk5YQvCaAISYCp]
//==================================================


/*
  Versión equivalente en C++:

  #include <iostream>
#include <string>

std::string decimalAHexadecimal(int numero) {
    if (numero == 0) return "0";

    std::string hexadecimal = "";
    char hexDigitos[] = "0123456789ABCDEF";

    while (numero > 0) {
        int residuo = numero % 16;
        hexadecimal = hexDigitos[residuo] + hexadecimal;
        numero /= 16;
    }

    return hexadecimal;
}

int main() {
    int numero;
    std::cout << "Ingresa un número decimal: ";
    std::cin >> numero;

    std::string hex = decimalAHexadecimal(numero);
    std::cout << "Hexadecimal: " << hex << std::endl;

    return 0;
}
Forma 2: Usando std::hex (formato de salida)
cpp
Copiar
Editar
#include <iostream>
#include <iomanip>

int main() {
    int numero;
    std::cout << "Ingresa un número decimal: ";
    std::cin >> numero;

    std::cout << "Hexadecimal: " << std::hex << std::uppercase << numero << std::endl;

    return 0;
}
 */

.global _start

// Sección de datos
.data
buffer:     .skip 20        // Buffer para guardar resultado
testnum:    .quad 0x1A3F    // Número de prueba (6719 en decimal)
digits:     .ascii "0123456789ABCDEF"
msg:        .ascii "Resultado: "
newline:    .ascii "\n"

// Sección de código
.text
_start:
    // Inicializar registros
    adr     x10, buffer     // Guardar dirección inicial del buffer
    mov     x1, x10         // Puntero actual al buffer
    
    // Cargar el número a convertir
    ldr     x0, testnum     // Cargar número a convertir
    
    // Poner prefijo "0x"
    mov     x2, #'0'        // Cargar '0'
    strb    w2, [x1], #1    // Guardar '0' en buffer
    mov     x2, #'x'        // Cargar 'x'
    strb    w2, [x1], #1    // Guardar 'x' en buffer
    
    // Si el número es 0, tratarlo especial
    cmp     x0, #0
    b.ne    convert_loop
    
    mov     x2, #'0'        // Cargar '0'
    strb    w2, [x1], #1    // Guardar '0' en buffer
    b       finish_convert
    
convert_loop:
    // Procesar número desde el bit más significativo
    mov     x2, #60         // Empezar con desplazamiento de 60 bits (16 nibbles)
    mov     x3, #0          // Bandera para ignorar ceros iniciales
    adr     x4, digits      // Tabla de dígitos hexadecimales
    
process_nibble:
    lsr     x5, x0, x2      // Desplazar bits a la derecha
    and     x5, x5, #0xF    // Mantener solo los 4 bits menos significativos
    
    // Verificar si es cero a la izquierda que debemos ignorar
    cmp     x3, #0          // ¿Ignorando ceros?
    b.ne    write_digit     // Si no, escribir dígito
    
    cmp     x5, #0          // ¿Es cero?
    b.eq    next_nibble     // Si es cero, saltar
    
    mov     x3, #1          // Activar bandera para escribir todos los dígitos
    
write_digit:
    // Escribir dígito hexadecimal
    ldrb    w6, [x4, x5]    // Obtener carácter
    strb    w6, [x1], #1    // Guardar en buffer
    
next_nibble:
    sub     x2, x2, #4      // Siguiente grupo de 4 bits
    cmp     x2, #0          // ¿Terminamos?
    b.ge    process_nibble  // Si no, continuar
    
finish_convert:
    // Agregar terminador nulo
    mov     w4, #0
    strb    w4, [x1]
    
    // Imprimir mensaje "Resultado: "
    mov     x0, #1          // fd = 1 (stdout)
    adr     x1, msg         // Dirección del mensaje
    mov     x2, #11         // Longitud "Resultado: "
    mov     x8, #64         // syscall write
    svc     #0
    
    // Imprimir resultado
    mov     x0, #1          // fd = 1 (stdout)
    mov     x1, x10         // Dirección del buffer (guardada en x10)
    
    // Calcular longitud
    sub     x2, x1, x10     // NO, esto no es correcto
    
    // En su lugar, recorremos el buffer para calcular la longitud
    mov     x2, #0          // Inicializar contador de longitud
    mov     x7, x10         // Copiar dirección inicial
length_loop:
    ldrb    w6, [x7, x2]    // Cargar byte
    cbz     w6, print_hex   // Si es nulo, terminar
    add     x2, x2, #1      // Incrementar contador
    b       length_loop     // Repetir
    
print_hex:
    // Ahora x2 contiene la longitud real
    mov     x1, x10         // Dirección del buffer
    mov     x8, #64         // syscall write
    svc     #0
    
    // Imprimir nueva línea
    mov     x0, #1          // fd = 1 (stdout)
    adr     x1, newline     // Dirección de nueva línea
    mov     x2, #1          // Longitud = 1
    mov     x8, #64         // syscall write
    svc     #0
    
    // Salir del programa
    mov     x0, #0          // Código de salida 0
    mov     x8, #93         // syscall exit
    svc     #0