GNU/Linux xterm-256color bash 115 views

// ****************************************************************************
// * Lenguajes de Interfaz en TECNM Campus ITT
// * Nombre del archivo: practica.s
// * Descripción: Programa que cuenta cuantos bits estan activados en u numero biario
// * Autor: [America Fernanda Nevarez de la Cruz]
// * Fecha: [2025-04-07]
// * Plataforma: Raspberry Pi OS (64 bits)
// * Demostración:  [https://asciinema.org/a/yF9AzJZkQzRY6aXEAIATfw0Jq]
// ****************************************************************************

// ****************************************************************************
// * Codigo equivalente en C
// *int main() {
// *    char buffer[64];
// *    int decimal = 0;
// *    int bit_count = 0;
// *
// *    // Mostrar mensaje
// *    printf("Ingrese un numero binario: ");
// *
// *    // Leer entrada del usuario
// *    fgets(buffer, sizeof(buffer), stdin);
// *    size_t length = strlen(buffer);
// *
// *    // Convertir binario a número decimal
// *    for(size_t i = 0; i < length; i++) {
// *        if(buffer[i] == '0') {
// *            decimal <<= 1;  // Desplazar y añadir 0
// *        } 
// *        else if(buffer[i] == '1') {
// *            decimal = (decimal << 1) | 1;  // Desplazar y añadir 1
// *        }
// *        // Ignorar otros caracteres (incluyendo \n)
// *    }
// *
// *    // Contar bits activados (1s)
// *    int temp = decimal;
// *    while(temp != 0) {
// *        bit_count += temp & 1;
// *        temp >>= 1;
// *    }
// *
// *    // Mostrar resultado
// *    printf("Cantidad de bits activados: %d\n", bit_count);
// *
// *    return 0;
// *}
// ****************************************************************************

.section .bss
buffer: .skip 64

.section .data
msg_ingrese: .ascii "Ingrese un numero binario: "
len_ingrese = . - msg_ingrese

msg_resultado: .ascii "Cantidad de bits activados: "
len_resultado = . - msg_resultado

newline: .ascii "\n"
len_nl = . - newline

.section .text
.global _start

_start:
    // Mostrar mensaje
    ldr x0, =msg_ingrese
    mov x1, #len_ingrese
    bl print_msg

    // Leer entrada del usuario
    mov x0, #0
    ldr x1, =buffer
    mov x2, #64
    mov x8, #63
    svc #0
    mov x9, x0              // x9 = longitud ingresada
    ldr x1, =buffer         // x1 apunta al buffer

    // Convertir binario (como texto) a número en x3
    mov x3, #0              // acumulador decimal

parse_loop:
    cbz x9, contar_bits
    ldrb w2, [x1], #1       // cargar caracter
    sub x9, x9, #1

    cmp w2, #'0'
    beq bit_0
    cmp w2, #'1'
    beq bit_1
    b parse_loop           // ignorar caracteres inválidos como '\n'

bit_0:
    lsl x3, x3, #1          // desplazar a la izquierda, añadir 0
    b parse_loop

bit_1:
    lsl x3, x3, #1
    orr x3, x3, #1          // añadir 1 al bit menos significativo
    b parse_loop

// Contar los bits en x3 (número convertido)
contar_bits:
    mov x4, x3              // copiar número
    mov x5, #0              // contador de bits activados

bit_count_loop:
    cbz x4, mostrar
    and x6, x4, #1
    add x5, x5, x6
    lsr x4, x4, #1
    b bit_count_loop

// Mostrar resultado
mostrar:
    ldr x0, =msg_resultado
    mov x1, #len_resultado
    bl print_msg

    mov x0, x5
    bl print_number

    // Imprimir newline
    ldr x0, =newline
    mov x1, #len_nl
    bl print_msg

    // Salida del programa
    mov x8, #93
    mov x0, #0
    svc #0

// --- Función para imprimir mensajes ---
print_msg:
    mov x2, x1     // longitud
    mov x1, x0     // puntero
    mov x0, #1     // stdout
    mov x8, #64
    svc #0
    ret

// --- Función para imprimir números ---
print_number:
    mov x1, x0
    ldr x2, =buffer
    add x2, x2, #63
    mov w3, #0

convert_loop:
    mov x4, #10
    udiv x5, x1, x4
    msub x6, x5, x4, x1     // x6 = x1 - x5*10
    add x6, x6, #'0'
    strb w6, [x2], #-1
    mov x1, x5
    add w3, w3, #1
    cbnz x1, convert_loop

    add x2, x2, #1
    mov x1, x2
    mov w2, w3
    mov x0, #1
    mov x8, #64
    svc #0
    ret