GNU/Linux xterm bash 162 views

Este código en ARM64 realiza varias operaciones, incluyendo la impresión de un número en binario y la cantidad de bits establecidos en 1 en ese número. A continuación te explico paso a paso lo que hace cada sección:

1. Definición de variables y constantes

.global _start

.section .data
msg_bin:    .ascii "Número original: 0b"
msg_bin_len = . - msg_bin

msg_bits:   .ascii "\nCantidad de bits en 1: "
msg_bits_len = . - msg_bits

buffer:     .skip 64        // Espacio para número binario y decimal
  • msg_bin: Se define una cadena de texto que se usará para imprimir el encabezado antes del número binario.
  • msg_bits: Se define otra cadena de texto para imprimir un mensaje con la cantidad de bits en 1.
  • buffer: Reserva espacio de 64 bytes para almacenar el número binario y la cantidad de bits en 1 como una cadena ASCII.

2. Inicio del código

.section .text

_start:
    mov x10, #0b110101       // Número original
    mov x0, x10              // x0 para conteo
    mov x1, #0               // x1: contador de bits en 1
  • x10: Se mueve el número binario 0b110101 (53 en decimal) a este registro, que es el número que se procesará.
  • x0: Se copia el número original en este registro para usarlo más adelante.
  • x1: Se inicializa como contador de bits establecidos en 1.

3. Imprimir “Número original: 0b”

    mov x0, #1
    ldr x1, =msg_bin
    mov x2, #msg_bin_len
    mov x8, #64
    svc #0
  • x0 = 1: Especifica que la salida será enviada a la consola.
  • x1: Se carga la dirección de msg_bin.
  • x2: Se mueve la longitud de msg_bin.
  • x8 = 64: Se configura la llamada al sistema para write (número de llamada del sistema).
  • svc #0: Realiza la llamada al sistema para imprimir el mensaje.

4. Generar la representación binaria

    ldr x3, =buffer          // Dirección del buffer
    mov x11, x10             // Copia del número original
    mov x4, #0               // x4: contador de bits

    mov x5, #6               // Número de bits del número original (máximo 6 para este ejemplo)
  • x3: Carga la dirección del buffer donde se almacenará el número binario.
  • x11: Copia del número original que se usará en la conversión.
  • x4: Contador para la posición de cada bit.
  • x5 = 6: Número de bits del número original (6 bits en este caso, ya que 0b110101 tiene 6 bits).

Luego, entra en un ciclo para procesar cada bit del número y generar la representación binaria:

gen_binary_loop:
    lsl x6, x11, x4          // Mover bit actual al MSB
    and x6, x6, 0b100000     // Mascarar solo ese bit
    cmp x6, #0
    b.eq write_0
    mov x7, #'1'
    b store_bit
write_0:
    mov x7, #'0'
store_bit:
    strb w7, [x3, x4]
    add x4, x4, #1
    cmp x4, x5
    b.lt gen_binary_loop
  • En cada iteración, mueve el bit más significativo del número original (en x11) a la izquierda, verifica si es 1 o 0, y lo almacena en el buffer.

5. Imprimir el número binario generado

    mov x0, #1
    ldr x1, =buffer
    mov x2, x4              // longitud = bits escritos
    mov x8, #64
    svc #0

Imprime el número binario generado, que está almacenado en buffer.

6. Contar los bits en 1

    mov x0, x10
    mov x1, #0              // Reset contador

count_loop:
    cbz x0, convert_to_ascii
    and x2, x0, #1
    add x1, x1, x2
    lsr x0, x0, #1
    b count_loop

Cuenta cuántos bits están establecidos en 1. Este ciclo:

  • Extrae el bit menos significativo de x0 (usando and).
  • Suma el valor a x1 si el bit es 1.
  • Luego realiza un desplazamiento lógico a la derecha para procesar el siguiente bit.

7. Convertir el número de bits en 1 a formato ASCII

convert_to_ascii:
    mov x2, x1              // Resultado del conteo
    ldr x3, =buffer
    add x3, x3, #63         // Apuntar al final del buffer
    mov x4, #0              // Contador de dígitos
    mov x7, #10             // Constante 10

Convierte el número de bits en 1 (almacenado en x1) a su representación ASCII y lo almacena en el buffer.

8. Imprimir el mensaje “Cantidad de bits en 1: “

print_msg:
    mov x0, #1
    ldr x1, =msg_bits
    mov x2, #msg_bits_len
    mov x8, #64
    svc #0

Imprime el mensaje "Cantidad de bits en 1: ".

9. Imprimir el número de bits en 1

print_number:
    ldr x1, =buffer
    add x1, x1, #64
    sub x1, x1, x4
    mov x0, #1
    mov x2, x4
    mov x8, #64
    svc #0

Imprime el número de bits en 1 que se calculó previamente.

10. Imprimir una nueva línea

print_newline:
    mov x0, #1
    ldr x1, =newline
    mov x2, #1
    mov x8, #64
    svc #0

Imprime una nueva línea.

11. Salir del programa

exit:
    mov x8, #93
    mov x0, #0
    svc #0

Hace una llamada al sistema para terminar la ejecución del programa.

12. Definir la nueva línea

.section .rodata
newline: .ascii "\n"

Define la constante de la nueva línea.

Resumen general:

El código en ARM64 imprime el número binario de un valor, cuenta cuántos bits en ese número están establecidos en 1 y muestra ambos resultados en la consola.