Introducción al lenguaje ensamblador para programadores

Índice

assembly language

El lenguaje ensamblador es un lenguaje de programación de bajo nivel que expone las instrucciones que utiliza el ordenador para operar su hardware. En este artículo, exploramos el lenguaje ensamblador como introducción a la programación con ejemplos de código y explicaciones. Si alguna vez te has preguntado qué es un «puntero» o una «pila» y si deberías aprender ensamblador para convertirte en programador, sigue leyendo. En este artículo se explica qué es el lenguaje ensamblador, sus ventajas y desventajas, ejemplos de casos de uso comunes de los lenguajes ensambladores y algunos recursos si deseas obtener más información sobre este tema. ¡Empecemos!

Definición de lenguaje ensamblador

El lenguaje ensamblador es un lenguaje de programación de bajo nivel específico para un tipo concreto de procesador. Suele escribirse en forma mnemotécnica, que es una representación simbólica del código máquina generado por el ensamblador. En el lenguaje ensamblador, los códigos de operación de las instrucciones de máquina se sustituyen por mnemónicos, y las direcciones de las instrucciones u operandos se sustituyen por símbolos de dirección o etiquetas. En diferentes dispositivos, el lenguaje ensamblador se corresponde con diferentes conjuntos de instrucciones de lenguaje máquina y se convierte en instrucciones de máquina mediante el proceso de ensamblaje. Existe una correspondencia uno a uno entre un lenguaje ensamblador específico y un conjunto de instrucciones de lenguaje máquina específico, y no es directamente portable entre diferentes plataformas.

Historia del lenguaje ensamblador

La historia del lenguaje ensamblador se remonta a los inicios de la informática. Uno de los primeros lenguajes ensambladores se creó en la década de 1950 para el ordenador IBM 701. Este lenguaje, denominado Autocode, fue desarrollado por Alick Glennie y se basaba en el código existente utilizado para el predecesor del 701, el IBM 650.

Al Autocode le siguieron pronto otros lenguajes ensambladores, como el lenguaje ensamblador FORTRAN (FAL) y el lenguaje ensamblador COBOL (CAL). Estos lenguajes se diseñaron para facilitar la programación en sus respectivos lenguajes de alto nivel y tuvieron mucho éxito.

Lenguaje de programación

Desde la llegada del primer ordenador electrónico del mundo en 1946, la forma y el lenguaje de comunicación entre los seres humanos y las máquinas se ha convertido en la principal línea de investigación de los ingenieros de software y los profesionales de la informática. Los lenguajes de programación más eficientes y sencillos se han convertido en los nuevos favoritos de los ingenieros de software. Con el rápido desarrollo de los ordenadores, la velocidad de actualización del hardware de los ordenadores es cada vez mayor y los requisitos para los lenguajes de programación son cada vez más estrictos. Los lenguajes de programación han avanzado mucho en las últimas décadas y, hasta la fecha, han existido tres generaciones de lenguajes. Con el fin de satisfacer los requisitos de programación y las funciones de software en diferentes campos, un gran número de lenguajes de programación han sido modificados, sustituidos y desarrollados, hasta llegar a la diversificación de los lenguajes de programación actuales. A pesar de los numerosos intentos por encontrar un lenguaje universal que se adapte a todos los entornos de programación, ninguno de ellos ha tenido éxito. El lenguaje de programación avanza a pasos agigantados con la tecnología moderna, y la sabiduría de los seres humanos se manifiesta cada vez más.

programming language
programming language

1.ª generación: lenguaje máquina

El lenguaje máquina es el lenguaje de programación de primera generación. Al principio de la invención del ordenador, para controlar el ordenador y completar sus propias tareas o proyectos, las personas solo podían escribir cadenas binarias de números como «0» y «1» para controlar el ordenador. Este lenguaje es el lenguaje máquina. Intuitivamente, el lenguaje máquina es muy oscuro y difícil de entender, y su significado a menudo se comprende consultando tablas o manuales. Es muy complicado de usar, especialmente cuando se necesita modificar el programa completado. Este tipo de lenguaje máquina desordenado te impedirá empezar y te resultará difícil encontrar errores en el programa. Además, el entorno operativo de cada ordenador es diferente, y las instrucciones y los métodos de funcionamiento también lo son. Por lo tanto, cuando se tiene una especificidad en este lenguaje máquina, solo se puede ejecutar en un ordenador específico. Y una vez que se cambia de máquina, es necesario reprogramar, lo que reduce en gran medida la eficiencia de uso y promoción del programa. Sin embargo, debido a la especificidad del lenguaje máquina, se adapta perfectamente a un tipo específico de ordenador, por lo que su eficiencia operativa es mucho mayor que la de otros lenguajes.

machine language
machine language

2.ª generación: lenguaje ensamblador

No es difícil darse cuenta de que el lenguaje máquina, como lenguaje de programación, tiene poca flexibilidad y legibilidad. Para aliviar las molestias que el lenguaje máquina causa a los ingenieros de software, se ha actualizado y mejorado: se utilizan letras y palabras fáciles de entender y recordar en lugar de instrucciones específicas. Gracias a este método, resulta fácil leer el programa completado o comprender la función que este realiza, y la reparación de errores y el funcionamiento y mantenimiento del programa existente se vuelven más fáciles y cómodos. Este lenguaje es lo que llamamos lenguaje ensamblador, el lenguaje informático de segunda generación.

assembly language (2)
assembly language

En comparación con el lenguaje máquina, el lenguaje ensamblador tiene una mayor dependencia de la máquina y es más fácil de recordar y escribir, pero al mismo tiempo conserva la alta velocidad y la gran eficiencia del lenguaje máquina. El lenguaje ensamblador sigue siendo un lenguaje orientado a la máquina, es difícil comprender la intención del diseño del programa a partir de su código y el programa diseñado no es fácil de trasplantar, por lo que no se utiliza tan ampliamente como la mayoría de los demás lenguajes informáticos de alto nivel. Por lo tanto, en los lenguajes de alto nivel altamente desarrollados de hoy en día, se suele utilizar en el nivel más básico, normalmente para la optimización de programas o el funcionamiento del hardware.

3.ª generación: lenguaje de alto nivel

Después de que el lenguaje de programación haya pasado por la actualización del lenguaje máquina, el lenguaje ensamblador, etc., se ha descubierto el factor clave que limita la generalización de los programas: la portabilidad de los programas. Es necesario diseñar un programa que pueda ejecutarse en diferentes máquinas independientemente del hardware del ordenador. De esta manera, se pueden evitar muchos procesos repetitivos de programación y se puede mejorar la eficiencia. Al mismo tiempo, el lenguaje debe estar cerca del lenguaje matemático o del lenguaje natural de los seres humanos. En la década de 1950, cuando los ordenadores aún eran escasos, nacieron los primeros lenguajes de programación de alto nivel. En aquella época, el coste de los ordenadores era elevado, pero la cantidad de cálculos diarios era limitada. Cómo utilizar eficazmente la limitada potencia de cálculo de los ordenadores se convirtió en un problema al que se enfrentaba la gente en aquella época. Al mismo tiempo, debido a la escasez de recursos, la eficiencia operativa de los ordenadores también se convirtió en el objetivo perseguido por los ingenieros de aquella época.

high level programming language
high-level programming language

Composición en lenguaje ensamblador

Debido al enorme sistema de instrucciones de ensamblaje, es necesario crear un sistema de instrucciones que tenga un gran número de instrucciones, formatos complejos y poca memorabilidad. La parte más difícil de la instrucción es el modo de direccionamiento que admite la instrucción, y su esencia es cómo obtener el operando en la instrucción. Para el procesador, se trata de cómo encontrar los datos que necesita. Sin embargo, para el lenguaje ensamblador en la parte inferior del ordenador, este método de direccionamiento implicará un gran número de formatos de almacenamiento informático y está estrechamente relacionado con el complejo método de gestión del almacenamiento, por lo que es difícil de entender. Por último, las instrucciones de ensamblaje también están relacionadas con cómo afectar a los indicadores, pero los indicadores del procesador son muy complejos, por lo que es más difícil comprender el mecanismo.

enviar comando

Las instrucciones del comando de envío incluyen:

  • instrucción de transferencia de datos generales: MOV;
  • instrucción de transferencia condicional: CMOVcc;
  • instrucción de operación de pila: PUSH, PUSHA, PUSHAD, POP, POPA, POPAD;
  • instrucción de intercambio: XCHG, XLAT, BSWAP;
  • instrucción de transferencia del selector de descriptor de dirección o segmento: LEA, LDS, LES, LFS, LGS, LSS, etc.

operación lógica

Esta parte de las instrucciones se utiliza para realizar operaciones aritméticas y lógicas, incluyendo:

  • instrucción de suma: ADD, ADC;
  • instrucción de resta: SUB, SBB;
  • instrucción más uno: INC;
  • instrucciones de ajuste decimal: AAA, AAS, DAA, DAS;
  • instrucción menos uno: DEC;
  • instrucción de operación de comparación: CMP;
  • instrucciones de extensión de signo: CBW, CWDE, CDQE;
  • instrucciones de multiplicación: MUL, IMUL;
  • instrucciones de división: DIV, IDIV;
  • instrucciones de operación lógica: AND, NOT, OR, XOR, TEST.

instrucción de cambio

Esta parte de la instrucción se utiliza para mover un registro u operando de memoria un número determinado de veces.

  • Instrucción de desplazamiento lógico a la izquierda: SHL;
  • instrucción de desplazamiento lógico a la derecha: SHR;
  • instrucción de desplazamiento aritmético a la izquierda: SAL;
  • instrucción de desplazamiento aritmético a la derecha: SAR;
  • instrucción de desplazamiento circular a la izquierda: ROL ;
  • instrucción de desplazamiento circular a la derecha: ROR, etc.

manipulación de bits

Esta parte de las instrucciones incluye:

  • la instrucción de prueba de bits: BT;
  • la instrucción de prueba y establecimiento de bits: BTS;
  • la instrucción de prueba y restablecimiento de bits: BTR;
  • la instrucción de prueba y negación de bits: BTC;
  • la instrucción de exploración hacia adelante de bits: BSF;
  • la instrucción de exploración hacia atrás de bits: BSR.

transferencia de control

Esta parte incluye:

  • instrucción de transferencia incondicional: JMP;
  • instrucción de transferencia condicional: JCC, JCXZ;
  • instrucción de bucle: LOOP, LOOPE, LOOPNE;
  • instrucción de llamada a procedimiento: CALL;
  • instrucción de retorno de subprocedimiento: RET;
  • instrucción de interrupción: INTn, INT3, INTO, IRET, etc.

Manipulación de cadenas

Esta parte de las instrucciones se utiliza para manejar la cadena de datos, incluyendo:

  • la instrucción de transferencia de cadena: MOVS;
  • la instrucción de comparación de cadenas: CMPS;
  • la instrucción de exploración de cadenas: SCANS;
  • la instrucción de guardado de cadenas: STOS;
  • la instrucción de carga de cadena: LODS.

Entrada Salida

Esta parte de las instrucciones se utiliza para intercambiar datos con dispositivos periféricos, incluyendo instrucciones de entrada de puerto IN/INS e instrucciones de salida de puerto OUT/OUTS.

Ejemplo de lenguaje ensamblador

Aquí hay un programa sencillo en lenguaje ensamblador que sumará dos números:

				
					; add.asm
;
; This program adds two numbers together
;

section .data

; These are the two numbers we will be adding
; We must store them in memory so the CPU can access them

num1: dw 1234
num2: dw 5678

section .text

; This is the code section of the program
; The code is a set of instructions for the CPU to execute

global _start

_start:

; Load the two numbers into registers
mov eax, [num1]
mov ebx, [num2]

; Add the numbers together
add eax, ebx

; Store the result in the num1 memory location
mov [num1], eax

; Exit the program
mov eax, 1
int 0x80
				
			

Características del lenguaje ensamblador

1. Dependencia de la máquina

Se trata de un lenguaje de bajo nivel orientado a la máquina, normalmente diseñado para un ordenador concreto o una familia de ordenadores. Dado que es una representación simbólica de las instrucciones de la máquina, cada máquina tiene un lenguaje ensamblador diferente.

2. Alta velocidad y alta eficiencia

El lenguaje ensamblador mantiene las ventajas del lenguaje máquina y tiene las características de ser directo y sencillo. Puede acceder y controlar eficazmente diversos dispositivos de hardware del ordenador, como discos, memoria, CPU, puertos de E/S, etc., y ocupa menos memoria y tiene una velocidad de ejecución rápida. Es un lenguaje de programación eficiente.

3. La complejidad de la escritura y la depuración

Dado que el hardware se controla directamente y las tareas sencillas también requieren muchas instrucciones en lenguaje ensamblador, es necesario cubrir todos los aspectos al diseñar programas. Es necesario tener en cuenta todos los problemas posibles y asignar y utilizar de forma razonable los distintos recursos de software y hardware. De este modo, inevitablemente aumentará la carga de trabajo del programador. Del mismo modo, al depurar un programa, una vez que surge un problema con el funcionamiento del programa, es difícil de detectar.

Ventajas

Como lenguaje de programación de segunda generación por encima del lenguaje máquina, el lenguaje ensamblador también tiene muchas ventajas:

  1. Puede leer fácilmente el estado de la memoria y el estado de la interfaz de E/S del hardware.
  2. El código escrito se puede ejecutar con precisión porque hay muchos menos enlaces de compilación.
  3. Como lenguaje de bajo nivel, es altamente extensible.

Desventajas

  1. Debido a que el código es muy monótono y hay pocos caracteres de instrucciones especiales, el código resulta prolijo y difícil de escribir.
  2. Dado que el ensamblador aún necesita llamar a la memoria para almacenar los datos por sí mismo, es fácil que haya errores y no es fácil depurarlo.
  3. Incluso si se completa un programa, su mantenimiento posterior requerirá mucho tiempo.
  4. Debido a la particularidad de la máquina, se produce el defecto de la mala compatibilidad del código.

Lenguaje ensamblador frente a lenguaje máquina

La principal diferencia entre el lenguaje ensamblador y el lenguaje máquina es que el lenguaje ensamblador es un lenguaje de programación de bajo nivel que requiere un ensamblador independiente para traducirlo a código máquina, mientras que el lenguaje máquina es una representación directa del código máquina subyacente.

El lenguaje ensamblador es más legible para los humanos que el lenguaje máquina, pero sigue siendo bastante difícil de leer y escribir. Está diseñado para ser similar al código máquina nativo, lo que facilita al programador comprender lo que hace el código. Sin embargo, esto también dificulta la escritura de código portátil, ya que el código está estrechamente vinculado a la arquitectura específica de la máquina.

El lenguaje máquina, por otro lado, es el código nativo de la máquina y no es legible para los humanos. Es ejecutado directamente por el procesador y, por lo tanto, es más eficiente que el lenguaje ensamblador. Sin embargo, es mucho más difícil de programar, ya que el programador debe lidiar con las instrucciones del código máquina subyacente.

Recursos para aprender lenguaje ensamblador

Si desea obtener más información sobre el lenguaje ensamblador, hay muchos recursos diferentes a su disposición. Puede encontrar libros sobre lenguaje ensamblador en Amazon y en las librerías locales. También puede encontrar cursos en línea en sitios web como Coursera, edX y Udemy. Si desea obtener más información sobre la arquitectura informática, también hay muchos libros sobre este tema. Estos recursos pueden ayudarle a comprender qué es el lenguaje ensamblador y sus implicaciones en el diseño de hardware y software informático.

Suscríbete

Únete a nuestra lista de suscriptores para recibir actualizaciones mensuales del blog, noticias de tecnología y estudios de caso. Nunca enviaremos spam y puedes cancelar tu suscripción en cualquier momento.

Acerca del Autor

Picture of Aidan Taylor
Aidan Taylor

I am Aidan Taylor and I have over 10 years of experience in the field of PCB Reverse Engineering, PCB design and IC Unlock.

¿Necesitas ayuda?

Scroll al inicio

Cotización