01. NASMx86: aprendiendo NASM for the lulz

Publicado por

El lenguaje ensamblador (assembly language) es uno de los lenguajes menos queridos por muchos programadores debido a la gran cantidad de detalles que se deben de considerar al estar escribiendo código en él. Con esta temporada aprenderás que no debes tener miedo de aprender ensamblador.

¿Qué es el lenguaje ensamblador?

Todo equipo de cómputo tiene un procesador que es el encargado de realizar las operaciones y los cálculos necesarios para resolver las tareas que le son asignadas. Estos procesadores solamente comprenden el lenguaje máquina o lenguaje binario (1 y 0), para una persona aprender a escribir lenguaje máquina puede ser muy complicado, es por ello que existe el lenguaje ensamblador que consta de una serie de directivas e instrucciones mnemónicas (fácilmente comprensible para el ser humano) que posteriormente son traducidas a código binario. En ensamblador se debe de ser muy preciso con las instrucciones de lo que queremos hacer, a diferencia de otros lenguajes más sofisticados que permiten tomarnos algunas libertades, esa es una de las características que lo hacen ser un lenguaje de bajo nivel.

El lenguaje ensamblador es propio para cada arquitectura, aunque es posible que algunas instrucciones y directivas sean similares entre algunas de ellas, lo cierto es que no se garantiza la compatibilidad total.

¿Por qué aprender ensamblador?

Son muchas las razones que un programador debe considerar para aprender ensamblador, cabe resaltar:

  • Permite comprender cómo trabaja el procesador de nuestra computadora al realizar tareas básicas como lectura/escritura de archivos, acceder a dispositivos, almacenar datos en memoria, etc. lo que se traduce en la posibilidad de optimizar código de otros lenguajes de alto nivel al comprender cómo estos trabajan internamente.
  • El tiempo de ejecución es menor que otros lenguajes de programación.
  • Permite controlar la forma en que se trabaja con hardware para algunos trabajos específicos como sistemas embebidos.
  • Aunque no vayas a programar sistemas completos en ensamblador, algunas tareas críticas pueden ser programadas en él para permitir el control total sobre ellas.
  • Si te gusta o utilizas mucho C o C++, aprender ensamblador te ayudará a mejorar mucho tus habilidades en ellos.

¿Por qué no aprender ensamblador?

Hay muy pocas cosas que se pueden hacer en ensamblador que no son posibles en lenguajes de más alto nivel como C. Si te interesa realizar programas grandes, ensamblador no es tu mejor opción. C permite hacer casi cualquier cosa que ensamblador puede hacer con un menor tiempo de desarrollo y más facilidad para mantener al día el código fuente.

Usos del lenguaje ensamblador

Algunos párrafos más arriba mencioné el uso de ensamblador en tareas críticas, estas pueden ser desde sistemas de seguridad para coches, aviones etc. hasta dispositivos médicos que deben trabajar con mucha precisión. La importancia del lenguaje ensamblador sobre otros lenguajes como C para esas tareas reside en que, a diferencia de los lenguajes de alto nivel, con ensamblador en verdad se tiene control total sobre la memoria que se utiliza y la forma que se utiliza. Los compiladores de alto nivel regularmente ponen algunas “barreras” para evitar estropearla o que funcione de forma extraña (acceder y modificar el apuntador de pila no es posible en C, por ejemplo).

La posibilidad de trabajar con tipos de datos primitivos y sus representaciones binarias de forma simple, también constituye una ventaja frente a otros lenguajes. Algunas operaciones binarias que regularmente requieren varios pasos en otros lenguajes, en ensamblador podrían requerir solo un par de instrucciones simples, lo cual se traduce en mayor rapidez de procesamiento.

Sobre esta temporada

A lo largo de esta serie de entradas aprenderás a programar para NASM (Nationwide Assembler), es decir aprenderás a programar para la familia de arquitectura x86 de Intel. Aunque la arquitectura permite escribir código para programas de 16, 32 y 64 bits, en esta temporada nos enfocaremos en instrucciones de 32 bits y en futuras temporadas haremos el salto a 64 bits. Este ensamblador soporta diferentes formatos como a.out de Linux y BSD , ELD, COFF, Mach-0, OBJ (OMG) de 16 y 32 bits, Win32, Win64 etc. Nosotros trabajaremos usando Ubuntu.

Al terminar esta temporada aprenderás a crear pequeños programas en ensamblador que podrás ejecutar directamente desde línea de comandos (posteriormente aprenderás a utilizar ensamblador junto con otros lenguajes).

Instalar NASM en Mac

Para instalar NASM en Mac sigue los siguientes pasos:

    1. Abre una ventana de Terminal.
    2. Ejecuta el siguiente comando y espera a que termine de procesarse:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null

    1. Ejecuta el siguiente comando:

brew install nasm

Listo, NASM está instalado en tu equipo.

Instalación en Linux (Ubuntu)

Ejecuta el siguiente comando:

sudo apt-get install nasm

Si el método anterior no funcionó, sigue los siguientes pasos:

    1. Descarga la última versión de NASM desde aquí.
    2. Descomprime el contenido, se creará una carpeta con un nombre como: nasm.x.x.x (donde x corresponde a la versión del ensamblador que descargaste).
    3. Ingresa desde Terminal a la carpeta que se creó en el paso anterior.
    4. Ejecuta el siguiente comando:

./configure

    1. Ejecuta el comando:

make

    1. Finalmente:

make install

Instalación en Windows

La instalación en Windows es muy sencilla, basta con descargar el ejecutable desde la página oficial, ejecutarlo y seguir las instrucciones del instalador.

Comprobar instalación en Linux y Mac

Para verificar si NASM se encuentra instalado en nuestro sistema utilizamos el siguiente comando:

whereis nasm

Si el ensamblador se encuentra instalado en el sistema, debería devolver una(s) ruta para acceder a él.

Ensamblar programa de prueba (hello, world!)

Vamos a ensamblar un programa para probar que NASM funciona correctamente.

Copia el siguiente código a un archivo de texto nuevo:


section .data
msg db 'Hello, world!', 0xa
len equ $ - msg

section .text
  global _start
_start:
  mov edx,len
  mov ecx,msg
  mov ebx,1
  mov eax,4
  int 0x80
  mov eax,1
  int 0x80

Guarda el archivo como “hello.asm”. Abre la carpeta donde está guardado el archivo desde Terminal y ejecuta los siguientes comandos:

nasm -f elf hello.asm
ld -m elf_i386 hello.o -o hello
./hello

Debería imprimirse el mensaje Hello, world! en Terminal… ¡Felicidades! Has ensamblado tu primer programa. En capítulos siguientes revisaremos con detenimiento la estructura de este programa.

Finalizando…

A lo largo de esta temporada aprenderás los temas básicos de ensamblador para permitirte crear pequeños programas y, posteriormente, nos adentraremos en temas un poco más complejos. Espero que lo visto en este primer capítulo haya sido de tu interés, cualquier duda puedes dejarla en la sección de comentarios. Hasta la próxima, see ya!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *