fbpx
Wikipedia

Lenguaje ensamblador

El lenguaje ensamblador o assembly (en inglés: assembly language y la abreviación asm) es un lenguaje de programación de bajo nivel. Consiste en un conjunto de mnemónicos que representan instrucciones básicas para los computadores, microprocesadores, microcontroladores y otros circuitos integrados programables. Implementa una representación simbólica de los códigos de máquina binarios y otras constantes necesarias para programar una arquitectura de procesador y constituye la representación más directa del código máquina específico para cada arquitectura legible por un programador. Cada arquitectura de procesador tiene su propio lenguaje ensamblador que usualmente es definida por el fabricante de hardware, y está basada en los mnemónicos que simbolizan los pasos de procesamiento (las instrucciones), los registros del procesador, las posiciones de memoria y otras características del lenguaje. Un lenguaje ensamblador es por lo tanto específico de cierta arquitectura de computador física (o virtual). Esto está en contraste con la mayoría de los lenguajes de programación de alto nivel, que idealmente son portables.

Lenguaje ensamblador


Motorola MC6800 Assembly listing
?
Información general
Extensiones comunes .asm
Paradigma Imperative, unstructured
Apareció en 1949
Lenguaje de máquina del Intel 8088. El código de máquina en hexadecimal se resalta en rojo, el equivalente en lenguaje ensamblador en magenta, y las direcciones de memoria donde se encuentra el código, en azul. Abajo se ve un texto en hexadecimal y ASCII.

Un programa utilitario llamado ensamblador es usado para traducir sentencias del lenguaje ensamblador al código de máquina del computador objetivo. El ensamblador realiza una traducción más o menos isomorfa (un mapeo de uno a uno) desde las sentencias mnemónicas a las instrucciones y datos de máquina. Esto está en contraste con los lenguajes de alto nivel, en los cuales una sola declaración generalmente da lugar a muchas instrucciones de máquina.

Muchos sofisticados ensambladores ofrecen mecanismos adicionales para facilitar el desarrollo del programa, controlar el proceso de ensamblaje, y la ayuda de depuración. Particularmente, la mayoría de los ensambladores modernos incluyen una facilidad de macro (descrita más abajo), y se llaman macro ensambladores.

Fue usado principalmente en los inicios del desarrollo de software, cuando aún no se contaba con potentes lenguajes de alto nivel y los recursos eran limitados. Actualmente se utiliza con frecuencia en ambientes académicos y de investigación, especialmente cuando se requiere la manipulación directa de hardware, alto rendimiento, o un uso de recursos controlado y reducido. También es utilizado en el desarrollo de controladores de dispositivo (en inglés, device drivers) y en el desarrollo de sistemas operativos, debido a la necesidad del acceso directo a las instrucciones de la máquina. Muchos dispositivos programables (como los microcontroladores) aún cuentan con el ensamblador como la única manera de ser manipulados.

Características

  • El código escrito en lenguaje ensamblador posee una cierta dificultad de ser entendido ya que su estructura se acerca al lenguaje máquina, es decir, es un lenguaje de bajo nivel.
  • El lenguaje ensamblador es difícilmente portable, es decir, un código escrito para un microprocesador, puede necesitar ser modificado, para poder ser usado en otra máquina distinta. Al cambiar a una máquina con arquitectura diferente, generalmente es necesario reescribirlo completamente.
  • Los programas hechos por un programador experto en lenguaje ensamblador pueden ser más rápidos y consumir menos recursos del sistema (ej: memoria RAM) que el programa equivalente compilado desde un lenguaje de alto nivel. Al programar cuidadosamente en lenguaje ensamblador se pueden crear programas que se ejecutan más rápidamente y ocupan menos espacio que con lenguajes de alto nivel. Conforme han evolucionado tanto los procesadores como los compiladores de lenguajes de alto nivel, esta característica del lenguaje ensamblador se ha vuelto cada vez menos significativa. Es decir, un compilador moderno de lenguaje de alto nivel puede generar código casi tan eficiente como su equivalente en lenguaje ensamblador.[1]
  • Con el lenguaje ensamblador se tiene un control muy preciso de las tareas realizadas por un microprocesador por lo que se pueden crear segmentos de código difíciles y/o muy ineficientes de programar en un lenguaje de alto nivel, ya que, entre otras cosas, en el lenguaje ensamblador se dispone de instrucciones del CPU que generalmente no están disponibles en los lenguajes de alto nivel.

Programa ensamblador

Generalmente, un programa ensamblador (assembler en inglés) moderno crea código objeto traduciendo instrucciones mnemónicas de lenguaje ensamblador en opcodes, y resolviendo los nombres simbólicos para las localizaciones de memoria y otras entidades.[2]​ El uso de referencias simbólicas es una característica clave del lenguaje ensamblador, evitando tediosos cálculos y actualizaciones manuales de las direcciones después de cada modificación del programa. La mayoría de los ensambladores también incluyen facilidades de macros para realizar sustitución textual - ej. generar cortas secuencias de instrucciones como expansión en línea en vez de llamar a subrutinas.

Los ensambladores son generalmente más simples de escribir que los compiladores para los lenguajes de alto nivel, y han estado disponibles desde los años 1950. Los ensambladores modernos, especialmente para las arquitecturas basadas en RISC, tales como MIPS, Sun SPARC, y HP PA-RISC, así como también para el x86 (-64), optimizan la planificación de instrucciones para explotar la segmentación del CPU eficientemente.

En los compiladores para lenguajes de alto nivel, son el último paso antes de generar el código ejecutable.

Número de pasos

Hay dos tipos de ensambladores basados en cuántos pasos a través de la fuente son necesarios para producir el programa ejecutable.

  • Los ensambladores de un solo paso pasan a través del código fuente una vez y asumen que todos los símbolos serán definidos antes de cualquier instrucción que los refiera.
  • Los ensambladores de dos pasos crean una tabla con todos los símbolos y sus valores en el primer paso, después usan la tabla en un segundo paso para generar código. El ensamblador debe por lo menos poder determinar la longitud de cada instrucción en el primer paso para que puedan ser calculadas las direcciones de los símbolos.

La ventaja de un ensamblador de un solo paso es la velocidad, que no es tan importante como lo fue en un momento dados los avances en velocidad y capacidades del computador. La ventaja del ensamblador de dos pasos es que los símbolos pueden ser definidos dondequiera en el código fuente del programa. Esto permite a los programas ser definidos de maneras más lógicas y más significativas, haciendo los programas de ensamblador de dos pasos más fáciles de leer y mantener.[3]

Ensambladores de alto nivel

Los más sofisticados ensambladores de alto nivel proporcionan abstracciones del lenguaje tales como:

  • Estructuras de control avanzadas
  • Declaraciones e invocaciones de procedimientos/funciones de alto nivel
  • Tipos de datos abstractos de alto nivel, incluyendo las estructuras/records, uniones, clases, y conjuntos
  • Procesamiento de macros sofisticado (aunque está disponible en los ensambladores ordinarios desde finales de los años 1960 para el IBM S/360, entre otras máquinas)
  • Características de programación orientada a objetos

Uso del término

Note que, en el uso profesional normal, el término ensamblador es frecuentemente usado tanto para referirse al lenguaje ensamblador como también al programa ensamblador (que convierte el código fuente escrito en el lenguaje ensamblador a código objeto que luego será enlazado para producir lenguaje de máquina). Las dos expresiones siguientes utilizan el término "ensamblador":

Lenguaje

El lenguaje ensamblador refleja directamente la arquitectura y las instrucciones en lenguaje de máquina de la CPU, y pueden ser muy diferentes de una arquitectura de CPU a otra.

Cada arquitectura de microprocesador tiene su propio lenguaje de máquina, y en consecuencia su propio lenguaje ensamblador ya que este se encuentra muy ligado a la estructura del hardware para el cual se programa. Los microprocesadores difieren en el tipo y número de operaciones que soportan; también pueden tener diferente cantidad de registros, y distinta representación de los tipos de datos en memoria. Aunque la mayoría de los microprocesadores son capaces de cumplir esencialmente las mismas funciones, la forma en que lo hacen difiere y los respectivos lenguajes ensamblador reflejan tal diferencia.

Instrucciones de CPU

La mayoría de las CPU tienen más o menos los mismos grupos de instrucciones, aunque no necesariamente tienen todas las instrucciones de cada grupo. Las operaciones que se pueden realizar varían de una CPU a otra. Una CPU particular puede tener instrucciones que no tenga otro y viceversa.

Los primeros microprocesadores de 8 bits no tenían operaciones para multiplicar o dividir números, por ejemplo, y había que hacer subrutinas para realizar esas operaciones. Otras CPU puede que no tengan operaciones de punto flotante y habría que hacer o conseguir bibliotecas que realicen esas operaciones.

Las instrucciones de la CPU pueden agruparse, de acuerdo a su funcionalidad, en:

Operaciones con enteros: (de 8, 16, 32 y 64 bits dependiendo de la arquitectura de la CPU, en los sistemas muy viejos también de 12, 18, 24, 36 y 48 bits).

Estas son operaciones realizadas por la Unidad aritmético lógica de la CPU:

  • Operaciones aritméticas. Como suma, resta, multiplicación, división, módulo, cambio de signo
  • Operaciones booleanas. Operaciones lógicas bit a bit como AND, OR, XOR, NOT
  • Operaciones de bits. Como desplazamiento o shift lógico y rotaciones u Operadores a nivel de bits (hacia la derecha o hacia la izquierda, a través del bit del acarreo o sin él)
  • Comparaciones

Operaciones de mover datos:

Entre los registros y la memoria:
Aunque la instrucción se llama "mover", en la CPU, "mover datos" significa en realidad copiar datos, desde un origen a un destino, sin que el dato desaparezca del origen.
Se pueden mover valores:
  • Desde un registro a otro
  • Desde un registro a un lugar de la memoria
  • Desde un lugar de la memoria a un registro
  • Desde un lugar a otro de la memoria
  • Un valor inmediato a un registro
  • Un valor inmediato a un lugar de memoria
Nota: Un valor inmediato es una constante que se especifica en la misma microinstrucción.
Operaciones de pila (stack, en inglés):
  • PUSH (escribe datos hacia el tope de la pila)
  • POP (lee datos desde el tope de la pila)
Operaciones de entrada/salida:
Son operaciones que mueven datos de un registro, desde y hacia un puerto; o de la memoria, desde y hacia un puerto
  • INPUT Lectura desde un puerto de entrada
  • OUTPUT Escritura hacia un puerto de salida

Operaciones para el control del flujo del programa:

  • Llamadas y retornos de subrutinas
  • Llamadas y retornos de interrupciones
  • Saltos condicionales de acuerdo al resultado de una comparación
  • Saltos incondicionales

Operaciones con números reales:

El estándar para las operaciones con números reales en las CPU está definido por el IEEE 754.

Una CPU puede tener operaciones de punto flotante con números reales mediante el coprocesador numérico (si lo hay), como las siguientes:

El lenguaje ensamblador tiene mnemónicos para cada una de las instrucciones de la CPU en adición a otros mnemónicos a ser procesados por el programa ensamblador (como por ejemplo macros y otras sentencias en tiempo de ensamblado).

Ensamblado

La transformación del lenguaje ensamblador en código máquina la realiza un programa ensamblador, y la traducción inversa la puede efectuar un desensamblador. A diferencia de los lenguajes de alto nivel, aquí hay usualmente una correspondencia 1 a 1 entre las instrucciones simples del ensamblador y el lenguaje de máquina. Sin embargo, en algunos casos, un ensamblador puede proveer "pseudo instrucciones" que se expanden en un código de máquina más extenso a fin de proveer la funcionalidad necesaria y simplificar la programación. Por ejemplo, para un código máquina condicional como "si X mayor o igual que", un ensamblador puede utilizar una pseudoinstrucción al grupo "haga si menor que", y "si = 0" sobre el resultado de la condición anterior. Los Ensambladores más completos también proveen un rico lenguaje de macros que se utiliza para generar código más complejo y secuencias de datos.

Para el mismo procesador y el mismo conjunto de instrucciones de CPU, diferentes programas ensambladores pueden tener, cada uno de ellos, variaciones y diferencias en el conjunto de mnemónicos o en la sintaxis de su lenguaje ensamblador. Por ejemplo, en un lenguaje ensamblador para la arquitectura x86, se puede expresar la instrucción para mover 5 al registro AL de la siguiente manera: MOV AL, 5, mientras que para otro ensamblador para la misma arquitectura se expresaría al revés: MOV 5, AL. Ambos lenguajes ensambladores harían exactamente lo mismo, solo que está expresado de manera diferente. El primero usa la sintaxis de Intel, mientras que el segundo usa la sintaxis de AT&T.

El uso del ensamblador no resuelve definitivamente el problema de cómo programar un sistema basado en microprocesador de modo sencillo ya que para hacer un uso eficiente del mismo, hay que conocer a fondo el microprocesador, los registros de trabajo de que dispone, la estructura de la memoria, y muchas cosas más referentes a su estructura básica de funcionamiento.

Ejemplos

Un programa escrito en lenguaje ensamblador consiste en una serie de instrucciones que corresponden al flujo de órdenes ejecutables por un microprocesador.

Por ejemplo, en el lenguaje ensamblador para un procesador x86:

La sentencia

  • MOV AL, 61h

Asigna el valor hexadecimal 61 (97 decimal) al registro "AL".

El programa ensamblador lee la sentencia de arriba y produce su equivalente binario en lenguaje de máquina.

  • Binario: 10110000 01100001 (hexadecimal: B061)

El mnemónico MOV es un código de operación u "opcode". El opcode es seguido por una lista de argumentos o parámetros, completando una típica instrucción de ensamblador. En el ejemplo, AL es un registro de 8 bits del procesador, al cual se le asignará el valor hexadecimal 61 especificado.

El código de máquina generado por el ensamblador consiste de 2 bytes. El primer byte contiene empaquetado la instrucción MOV y el código del registro hacia donde se va a mover el dato:

1011 0000 01100001 | | | | | +---- Número 61h en binario | |  | +--- Registro AL +-------- Instrucción MOV 

En el segundo byte se especifica el número 61h, escrito en binario como 01100001, que se asignará al registro AL, quedando la sentencia ejecutable como:

  • 10110000 01100001

La cual puede ser entendida y ejecutada directamente por el procesador.

Diseño del lenguaje

Elementos básicos

Hay un grado grande de diversidad en la manera en que los autores de los ensambladores categorizan las sentencias y en la nomenclatura que usan. En particular, algunos describen cualquier cosa como pseudo-operación (pseudo-Op), con excepción del mnemónico de máquina o del mnemónico extendido.

Un típico lenguaje ensamblador consiste en 3 tipos de sentencias de instrucción que son usadas para definir las operaciones del programa:

  • Mnemónicos de opcode
  • Secciones de datos
  • Directivas de ensamblador

Mnemónicos de opcode y mnemónicos extendidos

A diferencia de las instrucciones (sentencias) de los lenguajes de alto nivel, las instrucciones en el lenguaje ensamblador son generalmente muy simples. Generalmente, un mnemónico es un nombre simbólico para una sola instrucción en lenguaje de máquina ejecutable (un opcode), y hay por lo menos un mnemónico de opcode definido para cada instrucción en lenguaje de máquina. Cada instrucción consiste típicamente en una operación u opcode más cero o más operandos. La mayoría de las instrucciones refieren a un solo valor, o a un par de valores. Los operandos pueden ser inmediatos (típicamente valores de un byte, codificados en la propia instrucción), registros especificados en la instrucción, implícitos o las direcciones de los datos localizados en otra parte de la memoria. Esto está determinado por la arquitectura subyacente del procesador, el ensamblador simplemente refleja cómo trabaja esta arquitectura. Los mnemónicos extendidos son frecuentemente usados para especificar una combinación de un opcode con un operando específico, ej, el ensamblador del System/360 usa a B como un mnemónico extendido para el BC con una máscara de 15 y NOP al BC con una máscara de 0.

Los mnemónicos extendidos son frecuentemente usados para soportar usos especializados de instrucciones, a menudo para propósitos no obvios con respecto al nombre de la instrucción. Por ejemplo, muchos CPU no tienen una instrucción explícita de NOP (No Operación), pero tienen instrucciones que puedan ser usadas para tal propósito. En el CPU 8086, la instrucción XCHG AX,AX (intercambia el registro AX consigo mismo) es usada para el NOP, con NOP siendo un pseudo-opcode para codificar la instrucción XCHG AX,AX. Algunos desensambladores reconocen esto y decodificarán la instrucción XCHG AX,AX como NOP. Similarmente, los ensambladores de IBM para el System/360 usan los mnemónicos extendidos NOP y NOPR con las máscaras cero para BC y BCR.

Algunos ensambladores también soportan simples macroinstrucciones incorporadas que generan dos o más instrucciones de máquina. Por ejemplo, con algunos ensambladores para el Z80, la instrucción

LD HL, BC

genera las instrucciones

LD L, C
LD H, B.[4]

LD HL, BC es un pseudo-opcode, que en este caso simula ser una instrucción de 16 bits. Cuando se expande se producen dos instrucciones de 8 bits que equivalen a la simulada de 16 bits.

Secciones de datos

Hay instrucciones usadas para definir elementos de datos para manejar datos y variables. Definen el tipo de dato, la longitud y la alineación de los datos. Estas instrucciones también pueden definir si los datos están disponibles para programas exteriores (programas ensamblados separadamente) o solamente para el programa en el cual la sección de datos está definida. Algunos ensambladores clasifican estas instrucción como pseudo-instrucciones.

Directivas del ensamblador

Las directivas del ensamblador, también llamadas pseudo opcodes, pseudo-operaciones o pseudo-ops, son instrucciones que son ejecutadas por un ensamblador en el tiempo de ensamblado, no por la CPU en tiempo de ejecución. Pueden hacer al ensamblado del programa dependiente de parámetros especificados por el programador, de modo que un programa pueda ser ensamblado de diferentes maneras, quizás para diversas aplicaciones. También pueden ser usadas para manipular la presentación de un programa para hacerlo más fácil de leer y mantener.

Por ejemplo, las directivas pudieran ser usadas para reservar áreas de almacenamiento y opcionalmente para asignar su contenido inicial. Los nombres de las directivas a menudo comienzan con un punto para distinguirlas de las instrucciones de máquina.

Los ensambladores simbólicos le permiten a los programadores asociar nombres arbitrarios (etiquetas o símbolos) a posiciones de memoria. Usualmente, cada constante y variable tiene un nombre para que las instrucciones puedan referir a esas ubicaciones por nombre, así promoviendo el código autodocumentado. En el código ejecutable, el nombre de cada subprograma es asociado a su punto de entrada, así que cualquier llamada a un subprograma puede usar su nombre. Dentro de subprogramas, a los destinos GOTO se le dan etiquetas. Algunos ensambladores soportan símbolos locales que son léxicamente distintos de los símbolos normales (ej, el uso de "10$" como un destino GOTO).

La mayoría de los ensambladores proporcionan un manejo flexible de símbolos, permitiendo a los programadores manejar diversos espacios de nombres, calcular automáticamente offsets dentro de estructuras de datos, y asignar etiquetas que refieren a valores literales o al resultado de cálculos simples realizados por el ensamblador. Las etiquetas también pueden ser usadas para inicializar constantes y variables con direcciones relocalizables.

Los lenguajes ensambladores, como la mayoría de los otros lenguajes de computador, permiten que sean añadidos comentarios al código fuente, que son ignorados por el programa ensamblador. El buen uso de los comentarios es aún más importante con código ensamblador que con lenguajes de alto nivel, pues el significado y el propósito de una secuencia de instrucciones puede ser más difícil de entender a partir del código en sí mismo.

El uso sabio de estas facilidades puede simplificar significativamente los problemas de codificar y mantener el código de bajo nivel. El código fuente de lenguaje ensamblador crudo generado por compiladores o desensambladores - código sin ningún comentario, ni símbolos con algún sentido, ni definiciones de datos - es muy difícil de leer cuando deben hacerse cambios.

Macros

Muchos ensambladores soportan macros predefinidas, y otros soportan macros definidas (y repetidamente redefinibles) por el programador que implican secuencias de líneas del texto, en las cuales las variables y las constantes están embebidas. Esta secuencia de líneas de texto puede incluir opcodes o directivas. Una vez una macro se define, su nombre se puede usar en lugar de un mnemónico. Cuando el ensamblador procesa tal sentencia, reemplaza la sentencia por las líneas del texto asociadas a esa macro. Entonces, las procesa como si hubieran existido en el archivo del código fuente original (incluyendo, en algunos ensambladores, la expansión de cualquier macro que exista en el texto de reemplazo).

Puesto que las macros pueden tener nombres cortos pero se expanden a varias, o de hecho, muchas líneas de código, pueden usarse para hacer que los programas en lenguaje ensamblador parezcan ser mucho más cortos, requiriendo menos líneas de código fuente, como sucede con los lenguajes de alto nivel. También se pueden usar para añadir niveles de estructura más altos a los programas ensamblador; opcionalmente introducen código de depuración embebido vía parámetros y otras características similares.

Muchos ensambladores tienen macros incorporadas (o predefinidas) para las llamadas de sistema y otras secuencias especiales de código, tales como la generación y el almacenamiento de los datos realizados a través de avanzadas operaciones bitwise y operaciones booleanas usadas en juegos, software de seguridad, gestión de datos y criptografía.

Los macro ensambladores a menudo permiten a las macros tomar parámetros. Algunos ensambladores incluyen lenguajes macro sofisticados, incorporando elementos de lenguajes de alto nivel tales como parámetros opcionales, variables simbólicas, condiciones, manipulaciones de strings, operaciones aritméticas, todos usables durante la ejecución de una macro dada, y permitiendo a las macros guardar el contexto o intercambiar información. Así una macro puede generar un gran número de instrucciones o definiciones de datos en lenguaje ensamblador, basadas en los argumentos de la macro. Esto se podría usar para generar, por ejemplo, estructuras de datos de estilo de récord o bucles "desenrollados", o podría generar algoritmos enteros basados en parámetros complejos. Una organización, usando lenguaje ensamblador, que ha sido fuertemente extendido usando tal suite de macros, puede ser considerada que se está trabajando en un lenguaje de alto nivel, puesto que tales programadores no están trabajando con los elementos conceptuales de más bajo nivel del computador.

Las macros se usaron para personalizar sistemas de software de gran escala para clientes específicos en la era del mainframe. También se emplearon macros por los usuarios mismos para satisfacer las necesidades de sus organizaciones haciendo versiones específicas de los sistemas operativos del fabricante. Esto fue hecho, por ejemplo, por los programadores de sistema que trabajaban con el Conversational Monitor System / Virtual Machine (CMS/VM) de IBM y con los complementos real time transaction processing de IBM, CICS, Customer Information Control System, el airline/financial system que comenzó en los años 1970 y todavía corre con muchos sistemas de reservaciones computarizados (CRS) y sistemas de tarjeta de crédito de hoy.

También es posible usar solamente las habilidades de procesamiento de macros de un ensamblador para generar código escrito en lenguajes completamente diferentes. Por ejemplo, para generar una versión de un programa en COBOL usando un programa macro ensamblador puro conteniendo líneas de código COBOL dentro de operadores de tiempo ensamblaje dando instrucciones al ensamblador para generar código arbitrario.

Esto era porque, como en los años 1970 fue observado, el concepto de "procesamiento de macro" es independiente del concepto de "ensamblaje", siendo el anterior, en términos modernos, más un procesamiento de textos, que una generación de código objeto. El concepto de procesamiento de macro apareció, y aparece, en el lenguaje de programación C, que soporta "instrucciones de preprocesador" de fijar variables, y hace pruebas condicionales en sus valores. Observe que a diferencia de ciertos macroprocesadores previos dentro de los ensambladores, el preprocesador de C no es Turing-completo porque carecía de la capacidad de bucle o go to, esto último permitiendo a los programas hacer bucles.

A pesar del poder del procesamiento macro, este dejó de usarse en muchos lenguajes de alto nivel (una importante excepción es C/C++), pero persistió en los ensambladores. Esto era porque muchos programadores estaban bastante confundidos por la sustitución de parámetros macro y no distinguían la diferencia entre procesamiento macro, el ensamblaje y la ejecución.

La sustitución de parámetros macro es estrictamente por nombre: en el tiempo de procesamiento macro, el valor de un parámetro es sustituido textualmente por su nombre. La clase más famosa de Error de software resultantes era el uso de un parámetro que en sí mismo era una expresión y no un nombre primario cuando el escritor macro esperaba un nombre. En el macro:

foo: macro a
load a*b

la intención era que la rutina que llama proporcionaría el nombre de una variable, y la variable o constante "global b" sería usada para multiplicar a "a". Si foo se llama con el parámetro a-c, ocurre la expansión macro load a-c*b. Para evitar cualquier posible ambigüedad, los usuarios de macro procesadores pueden encerrar en paréntesis los parámetros formales dentro de las definiciones de macros, o las rutinas que llaman pueden envolver en paréntesis los parámetos de entrada.[5]​ Así, el macro correcto, con los paréntesis, sería:

foo: macro a
load (a)*b

y su expansión, daría como resultado: load (a-c)*b

El PL/I y el C/C++ ofrecen macros, pero esta facilidad solo puede manipular texto. Por otra parte, los lenguajes homoicónicos, tales como Lisp, Prolog, y Forth, retienen el poder de los macros de lenguaje ensamblador porque pueden manipular su propio código como datos.

Soporte para programación estructurada

Algunos ensambladores han incorporado elementos de programación estructurada para codificar el flujo de la ejecución. El ejemplo más temprano de este acercamiento estaba en el Concept-14 macro set, originalmente propuesto por el Dr. H.D. Mills (marzo de 1970), e implementado por Marvin Kessler en la Federal Systems Division de IBM, que extendió el macro ensamblador del S/360 con bloques de control de flujo IF/ELSE/ENDIF y similares.[6]​ Esto era una manera de reducir o eliminar el uso de operaciones GOTO en el código en lenguaje ensamblador, uno de los principales factores que causaban código espagueti en el lenguaje ensamblador. Este acercamiento fue ampliamente aceptado a principios de los años 1980 (los últimos días del uso de lenguaje ensamblador en gran escala).

Un curioso diseño fue A-natural, un ensamblador "orientado a la corriente" (stream-oriented) para los procesadores 8080/Z80[cita requerida] de Whitesmiths Ltd. (desarrolladores del sistema operativo Idris, similar al Unix), y lo que fue reportado como el primer compilador C comercial). El lenguaje fue clasificado como un ensamblador, porque trabajaba con elementos de máquina crudos tales como opcodes, registros, y referencias de memoria; pero incorporaba una sintaxis de expresión para indicar el orden de ejecución. Los paréntesis y otros símbolos especiales, junto con construcciones de programación estructurada orientadas a bloques, controlaban la secuencia de las instrucciones generadas. A-natural fue construido como el lenguaje objeto de un compilador C, en vez de la codificación manual, pero su sintaxis lógica ganó algunos seguidores.

Ha habido poca demanda aparente para ensambladores más sofisticados debido a la declinación del desarrollo de lenguaje ensamblador de larga escala.[7]​ A pesar de eso, todavía se están desarrollando y aplicando en casos donde las limitaciones de recursos o las particularidades en la arquitectura de sistema objetivo previenen el efectivo uso de lenguajes de alto nivel.[8]

Uso del lenguaje ensamblador

Perspectiva histórica

Los lenguajes ensambladores fueron primero desarrollados en los años 1950, cuando fueron referidos como lenguajes de programación de segunda generación. Por ejemplo, el SOAP (Symbolic Optimal Assembly Program) era un lenguaje ensamblador de 1957 para el computador IBM 650. Los lenguajes ensambladores eliminaron mucha de la propensión a errores y del consumo de tiempo de la programación de los lenguajes de primera generación, que se necesitaba con los primeros computadores, liberando a los programadores del tedio tal como recordar códigos numéricos y cálculo de direcciones. Una vez fueron ampliamente usados para todo tipo de programación. Sin embargo, por los años 1980 (1990 en los microcomputadores), su uso había sido en gran parte suplantado por los lenguajes de alto nivel,[cita requerida] en la búsqueda de una mejorada productividad en programación. Hoy en día, aunque el lenguaje ensamblador es casi siempre manejado y generado por los compiladores, todavía se usa para la manipulación directa del hardware, acceso a instrucciones especializadas del procesador, o para resolver problemas de desempeño crítico. Los usos típicos son controladores/manejadores (drivers) de dispositivo, sistemas embebidos de bajo nivel, y sistemas de tiempo real.

Históricamente, un gran número de programas han sido escritos enteramente en lenguaje ensamblador. Los sistemas operativos fueron casi exclusivamente escritos en lenguaje ensamblador hasta la aceptación amplia del lenguaje de programación C en los años 1970 y principios de los 1980. También, muchas aplicaciones comerciales fueron escritas en lenguaje ensamblador, incluyendo una gran cantidad del software escrito por grandes corporaciones para mainframes de IBM. Los lenguajes COBOL y FORTRAN eventualmente desplazaron mucho de este trabajo, aunque un número de organizaciones grandes conservaran las infraestructuras de aplicaciones en lenguaje ensamblador hasta bien entrados los años 1990.

La mayoría de los primeros microcomputadores confiaron en el lenguaje ensamblador codificado a mano, incluyendo la mayoría de los sistemas operativos y de las aplicaciones grandes. Esto era porque estos sistemas tenían limitaciones severas de recursos, impusieron idiosincráticas arquitecturas de memoria y de pantalla, y proporcionaron servicios de sistema limitados y con errores. Quizás más importante era la falta de compiladores de primera clase de lenguajes de alto nivel adecuados para el uso en el microcomputador. Un factor psicológico también pudo haber jugado un papel: la primera generación de programadores de los microcomputadores conservó una actitud de aficionado de "alambres y alicates".

En un contexto más comercial, las más grandes razones para usar el lenguaje ensamblador era hacer programas con mínimo tamaño, mínima sobrecarga, mayor velocidad y confiabilidad.

Los típicos ejemplos de programas grandes en lenguaje ensamblador de ese tiempo son los sistemas operativos IBM PC DOS y aplicaciones tempranas tales como la hoja de cálculo Lotus 1-2-3, y casi todos los juegos populares para la familia Atari 800 de computadores personales. Incluso en los años 1990, la mayoría de los videojuegos de consola fueron escritos en ensamblador, incluyendo la mayoría de los juegos para la Mega Drive/Genesis y el Super Nintendo Entertainment System.[cita requerida] Según algunos insiders de la industria, el lenguaje ensamblador era el mejor lenguaje de programación a usar para obtener el mejor desempeño del Sega Saturn, una consola para la cual era notoriamente desafiante desarrollar y programar juegos.[9]​ El popular juego de arcade NBA Jam (1993) es otro ejemplo. El ensamblador ha sido por largo trecho, el lenguaje de desarrollo primario en los computadores hogareños Commodore 64, Atari ST, así como el ZX Spectrum. Esto fue así en gran parte porque los dialectos del BASIC en estos sistemas ofrecieron insuficiente velocidad de ejecución, así como insuficientes características para aprovechar completamente el hardware disponible. Algunos sistemas, más notablemente el Amiga, incluso tienen IDEs con características de depuración y macros altamente avanzados, tales como el freeware ASM-One assembler, comparable a las del Microsoft Visual Studio (el ASM-Uno precede al Microsoft Visual Studio).

El ensamblador para el VIC-20 fue escrito por Don French y publicado por French Silk. Con 1639 bytes de longitud, su autor cree que es el más pequeño ensamblador simbólico jamás escrito. El ensamblador soportaba el direccionamiento simbólico usual y la definición de cadenas de caracteres o cadenas hexadecimales. También permitía expresiones de direcciones que podían combinarse con las operaciones de adición, sustracción, multiplicación, división, AND lógico, OR lógico, y exponenciación.[10]

Uso actual

Siempre ha habido debates sobre la utilidad y el desempeño del lenguaje ensamblador relativo a lenguajes de alto nivel. El lenguaje ensamblador tiene nichos específicos donde es importante (ver abajo). Pero, en general, los modernos compiladores de optimización para traducir lenguajes de alto nivel en código pueden correr tan rápidamente como el lenguaje ensamblador escrito a mano, a pesar de los contraejemplos que pueden ser encontrados.[11][12][13]​ La complejidad de los procesadores modernos y del subsistema de memoria hace la optimización efectiva cada vez más difícil para los compiladores, así como para los programadores en ensamblador.[14][15]​ Adicionalmente, y para la consternación de los amantes de la eficiencia, el desempeño cada vez mayor del procesador ha significado que la mayoría de los CPU estén desocupados la mayor parte del tiempo, con retardos causados por embotellamientos predecibles tales como operaciones de entrada/salida y paginación de memoria. Esto ha hecho que la velocidad de ejecución cruda del código no sea un problema para muchos programadores.

Hay algunas situaciones en las cuales los profesionales pudieran elegir utilizar el lenguaje ensamblador. Por ejemplo cuando:

  • Es requerido un ejecutable binario independiente (stand-alone), es decir uno que deba ejecutarse sin recursos a componentes de tiempo de ejecución o a bibliotecas asociadas con un lenguaje de alto nivel; ésta es quizás la situación más común. Son programas empotrados que solo almacenan una pequeña cantidad de memoria y el dispositivo está dirigido para hacer tareas para un simple propósito. Ejemplos consisten en teléfonos, sistemas de combustible e ignición para automóviles, sistemas de control del aire acondicionado, sistemas de seguridad, y sensores.
  • Interactuando directamente con el hardware, por ejemplo en controladores (drivers) de dispositivo y manejadores de interrupción.
  • Usando instrucciones específicas del procesador no explotadas o disponibles por el compilador. Un ejemplo común es la instrucción de rotación bitwise en el núcleo de muchos algoritmos de cifrado.
  • Creando funciones vectorizadas para programas en lenguajes de alto nivel como C. En el lenguaje de alto nivel esto es a veces ayudado por funciones intrínsecas del compilador que mapean directamente a los mnemónicos del SIMD, pero sin embargo resulta en una conversión de ensamblador de uno a uno para un procesador de vector asociado.
  • Es requerida la optimización extrema, ej, en un bucle interno en un algoritmo intensivo en el uso del procesador. Los programadores de juegos toman ventaja de las habilidades de las características del hardware en los sistemas, permitiendo a los juegos correr más rápidamente. También las grandes simulaciones científicas requieren algoritmos altamente optimizados, ej, álgebra lineal con BLAS o la transformada de coseno discreta (ej, la versión SIMD en ensamblador del x264,[16]​ (una biblioteca para codificar streams de video).
  • Un sistema con severas limitaciones de recursos (ej, un sistema empotrado) debe ser codificado a mano para maximizar el uso de los limitados recursos; pero esto está llegando a ser menos común a medida que el precio del procesador decrece y el desempeño mejora.
  • No existe ningún lenguaje de alto nivel, en un procesador nuevo o especializado.
  • Escribiendo programas de tiempo real que necesitan sincronización y respuestas precisas, tales como sistemas de navegación de vuelo, y equipo médico. Por ejemplo, en un sistema fly-by-wire (vuelo por mandos eléctricos), la telemetría debe ser interpretada y hay que actuar dentro de limitaciones estrictas de tiempo. Tales sistemas deben eliminar fuentes de retrasos impredecibles, que pueden ser creados por (algunos) lenguajes interpretados, recolección de basura automática, operaciones de paginación, o multitarea apropiativa. Sin embargo, algunos lenguajes de alto nivel incorporan componentes de tiempo de ejecución e interfaces de sistema operativo que pueden introducir tales retrasos. Elegir el ensamblador o lenguajes de bajo nivel para tales sistemas da a los programadores mayor visibilidad y control sobre los detalles del procesamiento.
  • Es requerido control total sobre el ambiente, en situaciones de seguridad extremadamente alta donde nada puede darse por sentado.
  • Se escriben virus de computadora, bootloaders, ciertos controladores/manejadores de dispositivo, u otros elementos muy cerca del hardware o al sistema operativo de bajo nivel.
  • Se escriben simuladores del conjunto de instrucciones para monitoreo, trazado y depuración de errores donde la sobrecarga adicional es mantenida al mínimo.
  • Se hace ingeniería inversa en binarios existentes que pueden o no haber sido escritos originalmente en un lenguaje de alto nivel, por ejemplo al crackear la protección anticopia del software propietario.
  • Se hace ingeniería inversa y modificación de video juegos (también denominado ROM hacking), que es posible por medio de varios métodos. El más ampliamente implementado es alterando el código del programa a nivel de lenguaje ensamblador.
  • Se escribe código automodificable (también conocido como polimórfico), algo para lo que el lenguaje ensamblador se presta bien.
  • Se escriben juegos y otros softwares para calculadoras gráficas.[17]
  • Se escribe software compilador que genera código ensamblador, y por lo tanto los desarrolladores deben ser programadores de lenguaje ensamblador.
  • Se escriben algoritmos criptográficos que siempre deben tomar estrictamente el mismo tiempo para ejecutar, previniendo ataques de tiempo.

Sin embargo, el lenguaje ensamblador es todavía enseñado en la mayoría de los programas de ciencias de la computación e ingeniería electrónica. Aunque hoy en día, pocos programadores trabajan regularmente con el lenguaje ensamblador como una herramienta, los conceptos fundamentales continúan siendo muy importantes. Tales tópicos fundamentales, como aritmética binaria, asignación de memoria, procesamiento del stack, codificación de conjunto de caracteres, procesamiento de interrupciones, y diseño de compiladores, serían duros de estudiar en detalle sin la comprensión de cómo el computador opera a nivel del hardware. Puesto que el comportamiento del computador es fundamentalmente definido por su conjunto de instrucciones, la manera lógica de aprender tales conceptos es estudiar un lenguaje ensamblador. La mayoría de los computadores modernos tienen un conjunto de instrucciones similares. Por lo tanto, estudiar un solo lenguaje ensamblador es suficiente para aprender: i) los conceptos básicos; ii) reconocer situaciones donde el uso de lenguaje ensamblador puede ser apropiado; y iii) ver cómo el código ejecutable eficiente puede ser creado por los lenguajes de alto nivel[18]

Aplicaciones típicas

El lenguaje ensamblador hard-coded es típicamente usado en el ROM de arranque del sistema (BIOS en los sistemas compatible IBM PC). Este código de bajo nivel es usado, entre otras cosas, para inicializar y probar el hardware del sistema antes de cargar el sistema operativo, y está almacenado en el ROM. Una vez que ha tomado lugar un cierto nivel de inicialización del hardware, la ejecución se transfiere a otro código, típicamente escrito en lenguajes de alto nivel; pero el código corriendo inmediatamente después de que es aplicada la energía usualmente está escrito en lenguaje ensamblador. Lo mismo es cierto para los boot loaders.

Muchos compiladores traducen lenguajes de alto nivel a lenguaje ensamblador primero, antes de la compilación completa, permitiendo que el código en ensamblador sea visto para propósitos de depuración y optimización. Lenguajes de relativo bajo nivel, como C, con frecuencia proveen sintaxis especial para empotrar lenguaje ensamblador en cada plataforma de hardware. El código portable del sistema entonces puede usar estos componentes específicos a un procesador a través de una interface uniforme.

El lenguaje ensamblador también es valioso en ingeniería inversa, puesto que muchos programas solamente son distribuidos en una forma de código de máquina. El código de máquina es usualmente fácil de trasladar hacia lenguaje ensamblador para luego ser cuidadosamente examinado en esta forma, pero es muy difícil de trasladar hacia un lenguaje de alto nivel. Herramientas como Interactive Disassembler, hacen uso extenso del desensamblador para tales propósitos.

Un nicho que hace uso del lenguaje ensamblador es el demoscene. Ciertas competiciones requieren a los concursantes restringir sus creaciones a un muy pequeño tamaño (ej, 256 bytes, 1 KB, 4 KB o 64 KB), y el lenguaje ensamblador es el lenguaje de preferencia para alcanzar este objetivo.[19]​ Cuando los recursos son una preocupación, es una necesidad la codificación en ensamblador, especialmente en sistemas constreñidos por el procesamiento del CPU, como los primeros modelos del Amiga, y el Commodore 64. El código optimizado en ensamblador es escrito "a mano" por los programadores en un intento de minimizar el número de ciclos de CPU usados. Las limitaciones del CPU son tan grandes que cada ciclo cuenta. Usar tales métodos ha habilitado, a sistemas como el Commodore 64, para producir gráficos en 3D en tiempo real con efectos avanzados, una hazaña que puede ser considerada improbable o incluso imposible para un sistema con un procesador de 0.99 MHz.[cita requerida]

Detalles adicionales

Para un determinado computador personal, mainframe, sistema empotrado, y consola de juegos, tanto del pasado como del presente, ha sido escrito al menos uno, y posiblemente docenas de ensambladores. Para algunos ejemplos, vea la lista de ensambladores.

En los sistemas Unix, el ensamblador es llamado tradicionalmente as, aunque no es un simple cuerpo de código, siendo típicamente escrito uno nuevo por cada port. Un número de variantes de Unix usan el GAS

Dentro de los grupos de procesadores, cada ensamblador tiene su propio dialecto. A veces, algunos ensambladores pueden leer el dialecto de otro, por ejemplo, TASM puede leer el viejo código del MASM, pero no al revés. FASM y NASM tienen una sintaxis similar, pero cada uno soporta diferentes macros que pueden ser difícil de trasladar de uno al otro. Las cosas básicas son siempre las mismas, pero las características avanzadas serán diferentes[20]

También, los lenguajes ensambladores a veces pueden ser portables a través de diferentes sistemas operativos en el mismo tipo de CPU. Las convenciones de llamadas entre los sistemas operativos con frecuencia difieren ligeramente o en nada. y con cuidado es posible ganar portabilidad en el lenguaje ensamblador, usualmente al enlazar con una biblioteca de lenguaje C que no cambia entre sistemas operativos. Un simulador de conjunto de instrucciones (que idealmente sería escrito en lenguaje ensamblador) puede, en teoría, procesar el código objeto/binario de cualquier ensamblador) para lograr la portabilidad incluso a través de plataformas (con una sobrecargue no mayor que la de un interpretador de bytecode típico). Esto es esencialmente lo que logra el microcódigo cuando una plataforma de hardware cambia internamente.

Por ejemplo, muchas cosas en libc dependen del preprocesador para hacer, al programa antes de compilar, cosas que son específicas del sistema operativo o específicas del C. De hecho, algunas funciones y símbolos ni siquiera están garantizados que existan fuera del preprocesador. Peor aún, el tamaño y el orden de los campos de las estructuras, tanto como el tamaño de ciertas typedefs como off_t, no están disponibles en lenguaje ensamblador sin la ayuda de un script de configuración, y difieren incluso entre versiones de Linux, haciendo imposible portar llamadas de funciones en libc diferentes de los que toman simples enteros o punteros como parámetros. Para manejar estos problemas, el proyecto FASMLIB provee una biblioteca de lenguaje ensamblador portable para las plataformas Win32 y Linux, pero todavía está muy incompleta.[21]

Algunos lenguajes de muy alto nivel, como C y Borland/Pascal, soportan ensamblado en línea, donde relativamente secciones cortas de código en ensamblador puede ser empotradas dentro del código del lenguaje de alto nivel. El lenguaje Forth comúnmente contiene un ensamblador usado para codificar palabras.

La mayoría de la gente usa un emulador para depurar sus programas en lenguaje ensamblador.

Ejemplos de lenguaje ensamblador

Ejemplo para la arquitectura x86

El siguiente es un ejemplo del programa clásico Hola mundo escrito para la arquitectura de procesador x86 (bajo el sistema operativo DOS).

; --------------------------------------------- ; Programa que imprime un string en la pantalla ; --------------------------------------------- .model small  ; modelo de memoria .stack  ; segmento del stack .data  ; segmento de datos Cadena1 DB 'Hola Mundo. ; string a imprimir (finalizado en $) .code  ; segmento del código ; --------------------------------------------- ; Inicio del programa ; --------------------------------------------- programa: ; ---------------------------------------------------------------------------------------------------- ; inicia el segmento de datos ; ---------------------------------------------------------------------------------------------------- MOV AX, @data ; carga en AX la dirección del segmento de datos MOV DS, AX  ; mueve la dirección al registro de segmento por medio de AX ; ---------------------------------------------------------------------------------------------------- ; Imprime un string en pantalla ; ---------------------------------------------------------------------------------------------------- MOV DX, offset Cadena1 ; mueve a DX la dirección del string a imprimir MOV AH, 9  ; AH = código para indicar al MS DOS que imprima en la pantalla, el string en DS:DX INT 21h  ; llamada al MS DOS para ejecutar la función (en este caso especificada en AH) ; ---------------------------------------------------------------------------------------------------- ; Finaliza el programa ; ---------------------------------------------------------------------------------------------------- INT 20h  ; llamada al MS DOS para finalizar el programa end programa 

Ejemplo para el computador virtual (POCA)

Una selección de instrucciones para una computadora virtual[22]​) con las correspondientes direcciones de memoria en las que se ubicarán las instrucciones. Estas direcciones NO son estáticas. Cada instrucción se acompaña del código en lenguaje ensamblador generado (código objeto) que coincide con la arquitectura de computador virtual, o conjunto de instrucciones ISA.

Dir. Etiqueta Instrucción Código máquina[23]
.begin
.org 2048
a_start .equ 3000
2048 ld [length], %r1
2064 be done 00000010 10000000 00000000 00000110
2068 addcc %r1,-4,%r1 10000010 10000000 01111111 11111100
2072 addcc %r1,%r2,%r4 10001000 10000000 01000000 00000010
2076 ld %r4,%r5 11001010 00000001 00000000 00000000
2080 ba loop 00010000 10111111 11111111 11111011
2084 addcc %r3,%r5,%r3 10000110 10000000 11000000 00000101
2088 done: jmpl %r15+4,%r0 10000001 11000011 11100000 00000100
2092 length: 20 00000000 00000000 00000000 00010100
2096 address: a_start 00000000 00000000 00001011 10111000
.org a_start
3000 a:

Ejemplo para el computador virtual (ARC)

ARC es un subconjunto del modelo de arquitectura basado en el procesador SPARC. ARC ( A RISC Computer) contiene la mayoría de las características

importantes de la arquitectura SPARC.

Dirección Etiqueta Instrucción Comentarios
.begin
.org 2048
a_start: .equ 3000 ! Dirección de memoria del arreglo comienza en 3000
2048 ld [lenght], %r1 ! Se establece la longitud del arreglo en el registro
2052 ld [address], %r2 ! Dirección del arreglo a
2056 anddcc %r3, %r0, %r3 ! Se establece con cero la suma parcial
2060 loop: anddcc %r1, %r1, %r0 ! Verifico si r1 tiene elementos restantes
2064 be done
2068 addcc %r1, -4, %r1 !Decremento el tamaño del arreglo
2072 ld %r1 + %r2, %r4 !Cargo el próximo elemento en r4
2076 addcc %r3, %r4, %r3 ! Actualizo la suma parcial en r3
2080 ba loop ! Vuelve a verificar la condición de corte
2084 done: jmpl %r15 + 4, %r0 ! Retorno a la rutina principal
2088 lenght: 20 ! Tamaño del arreglo en 20 bytes, 5 números
2092 address: a_start
.org a_start ! Comienzo del arreglo a
a: 25
15
-20
-35
15
.end ! Fin del programa


Ejemplo para el µC Intel 8051

Código en lenguaje ensamblador para µC Intel 80C51:

 ORG 8030H include T05SEG: SETB TR0 JNB uSEG,T05SEG ;esta subrutina es utilizada CLR TR0 ;para realizar una cuenta de CPL uSEG ;0,5 segundos mediante la MOV R1,DPL ;interrupción del timer 0. INVOKE MOV R2,DPH CJNE R2,#07H,T05SEG CJNE R1,#78H,T05SEG MOV DPTR,#0 RET 

Ejemplo para el Microchip PIC16F84

Código en lenguaje ensamblador para el microcontrolador 16F84 de Microchip:

 ORG 0 Inicio bcf STATUS,RP0 clrf PORTB movlw 0xFF movwf PORTA bsf STATUS,RP0 Principal movf PORTA,W movwf Contador movf Contador,F btfsc STATUS,Z goto PuntoDecimal sublw d'9' btfss STATUS,C END 

Véase también

Ensambladores

Desensambladores

Depuradores

Otros

Sistemas operativos escritos completamente en assembler:

Referencias

  1. "DSP: C versus Assembly", Steven W. Smith, Ph.D., 2011
  2. David Salomon (1993). Assemblers and Loaders
  3. Beck, Leland L. (1996). «2». System Software: An Introduction to Systems Programming. Addison Wesley. 
  4. http://www.z80.de/z80/z80code.htm
  5. «Macros (C/C++), MSDN Library for Visual Studio 2008». Microsoft Corp. Consultado el 22 de junio de 2010. 
  6. «Concept 14 Macros». MVS Software. Consultado el 25 de mayo de 2009. 
  7. Answers.com. «assembly language: Definition and Much More from Answers.com». Consultado el 19 de junio de 2008. 
  8. NESHLA: The High Level, Open Source, 6502 Assembler for the Nintendo Entertainment System
  9. . Archivado desde el original el 13 de julio de 2008. Consultado el 25 de julio de 2008. 
  10. Jim Lawless (21 de mayo de 2004). . Archivado desde el original el 21 de agosto de 2008. Consultado el 25 de julio de 2008. 
  11. «Writing the Fastest Code, by Hand, for Fun: A Human Computer Keeps Speeding Up Chips». New York Times, John Markoff. 28 de noviembre de 2005. Consultado el 4 de marzo de 2010. 
  12. . hardwarebug.org. 30 de enero de 2010. Archivado desde el original el 5 de febrero de 2010. Consultado el 4 de marzo de 2010. 
  13. . hardwarebug.org. 13 de mayo de 2009. Archivado desde el original el 16 de marzo de 2010. Consultado el 4 de marzo de 2010. 
  14. Randall Hyde. . Archivado desde el original el 16 de junio de 2008. Consultado el 3 de julio de 2008. 
  15. . hardwarebug.org. 30 de enero de 2010. Archivado desde el original el 2 de abril de 2010. Consultado el 4 de marzo de 2010. 
  16. . git.videolan.org. 29 de septiembre de 2010. Archivado desde el original el 4 de marzo de 2012. Consultado el 29 de septiembre de 2010. 
  17. «68K Programming in Fargo II». Consultado el 3 de julio de 2008. 
  18. Hyde, Randall (30 de septiembre de 1996). . Archivado desde el original el 22 de febrero de 2010. Consultado el 5 de marzo de 2010. 
  19. «256bytes demos archives». Consultado el 3 de julio de 2008. 
  20. Randall Hyde. . Archivado desde el original el 18 de octubre de 2007. Consultado el 19 de octubre de 2007. 
  21. "vid". «FASMLIB: Features». Consultado el 19 de octubre de 2007. 
  22. (POCA) – ARCTools computadora virtual disponible para descarga y ejecución del código, acceso el 24 de agosto de 2005
  23. Murdocca, Miles J. y Heuring, Vincent P.:Principles of Computer Architecture (2000), Prentice Hall, ISBN 0-201-43664-7

Bibliografía

  • Dominic Sweetman: See MIPS Run. Morgan Kaufmann Publishers, 1999. ISBN 1-55860-410-3
  • Robert Britton: MIPS Assembly Language Programming. Prentice Hall, 2003. ISBN 0-13-142044-5
  • John Waldron: Introduction to RISC Assembly Language Programming. Addison Wesley, 1998. ISBN 0-201-39828-1
  • "An online book full of helpful ASM info, tutorials and code examples" by the ASM Community
  • Jonathan Bartlett: Programming from the Ground Up. Bartlett Publishing, 2004. ISBN 0-9752838-4-7
    Also available online as PDF el 6 de febrero de 2009 en Wayback Machine.
  • Paul Carter: PC Assembly Language. Free ebook, 2001.
    Website
  • Jeff Duntemann: Assembly Language Step-by-Step. Wiley, 2000. ISBN 0-471-37523-3
  • Randall Hyde: The Art of Assembly Language. No Starch Press, 2003. ISBN 1-886411-97-2
    Draft versions as PDF and HTML
  • Peter Norton, John Socha, Peter Norton's Assembly Language Book for the IBM PC, Brady Books, NY: 1986.
  • Michael Singer, PDP-11. Assembler Language Programming and Machine Organization, John Wiley & Sons, NY: 1980.
  • Principios de arquitectura de computadoras - Miles J. Murdocca - Vincent P. Heuring

Enlaces externos

  •   Wikilibros alberga un libro o manual sobre Programación en lenguaje ensamblador.
  • ,
  • Computer-Books.us, Online Assembly Language Brooks
  • PC Assembly Tutorial using NASM and GCC by Paul Carter
  • Programming from the Ground Up by Jonathan Bartlett
  • by the ASM Community
  • Inline::ASM módulo Perl en CPAN para programar en lenguaje ensamblador dentro de programas Perl (en inglés)
  •   Datos: Q165436
  •   Multimedia: Assemblers
  •   Libros y manuales: Programación en lenguaje ensamblador

lenguaje, ensamblador, para, otros, usos, este, término, véase, ensamblador, desambiguación, lenguaje, ensamblador, assembly, inglés, assembly, language, abreviación, lenguaje, programación, bajo, nivel, consiste, conjunto, mnemónicos, representan, instruccion. Para otros usos de este termino vease Ensamblador desambiguacion El lenguaje ensamblador o assembly en ingles assembly language y la abreviacion asm es un lenguaje de programacion de bajo nivel Consiste en un conjunto de mnemonicos que representan instrucciones basicas para los computadores microprocesadores microcontroladores y otros circuitos integrados programables Implementa una representacion simbolica de los codigos de maquina binarios y otras constantes necesarias para programar una arquitectura de procesador y constituye la representacion mas directa del codigo maquina especifico para cada arquitectura legible por un programador Cada arquitectura de procesador tiene su propio lenguaje ensamblador que usualmente es definida por el fabricante de hardware y esta basada en los mnemonicos que simbolizan los pasos de procesamiento las instrucciones los registros del procesador las posiciones de memoria y otras caracteristicas del lenguaje Un lenguaje ensamblador es por lo tanto especifico de cierta arquitectura de computador fisica o virtual Esto esta en contraste con la mayoria de los lenguajes de programacion de alto nivel que idealmente son portables Lenguaje ensambladorMotorola MC6800 Assembly listing Informacion generalExtensiones comunes asmParadigmaImperative unstructuredAparecio en1949 editar datos en Wikidata Lenguaje de maquina del Intel 8088 El codigo de maquina en hexadecimal se resalta en rojo el equivalente en lenguaje ensamblador en magenta y las direcciones de memoria donde se encuentra el codigo en azul Abajo se ve un texto en hexadecimal y ASCII Un programa utilitario llamado ensamblador es usado para traducir sentencias del lenguaje ensamblador al codigo de maquina del computador objetivo El ensamblador realiza una traduccion mas o menos isomorfa un mapeo de uno a uno desde las sentencias mnemonicas a las instrucciones y datos de maquina Esto esta en contraste con los lenguajes de alto nivel en los cuales una sola declaracion generalmente da lugar a muchas instrucciones de maquina Muchos sofisticados ensambladores ofrecen mecanismos adicionales para facilitar el desarrollo del programa controlar el proceso de ensamblaje y la ayuda de depuracion Particularmente la mayoria de los ensambladores modernos incluyen una facilidad de macro descrita mas abajo y se llaman macro ensambladores Fue usado principalmente en los inicios del desarrollo de software cuando aun no se contaba con potentes lenguajes de alto nivel y los recursos eran limitados Actualmente se utiliza con frecuencia en ambientes academicos y de investigacion especialmente cuando se requiere la manipulacion directa de hardware alto rendimiento o un uso de recursos controlado y reducido Tambien es utilizado en el desarrollo de controladores de dispositivo en ingles device drivers y en el desarrollo de sistemas operativos debido a la necesidad del acceso directo a las instrucciones de la maquina Muchos dispositivos programables como los microcontroladores aun cuentan con el ensamblador como la unica manera de ser manipulados Indice 1 Caracteristicas 2 Programa ensamblador 2 1 Numero de pasos 2 2 Ensambladores de alto nivel 2 3 Uso del termino 3 Lenguaje 3 1 Instrucciones de CPU 3 2 Ensamblado 3 3 Ejemplos 4 Diseno del lenguaje 4 1 Elementos basicos 4 1 1 Mnemonicos de opcode y mnemonicos extendidos 4 1 2 Secciones de datos 4 1 3 Directivas del ensamblador 4 2 Macros 4 3 Soporte para programacion estructurada 5 Uso del lenguaje ensamblador 5 1 Perspectiva historica 5 2 Uso actual 5 3 Aplicaciones tipicas 6 Detalles adicionales 7 Ejemplos de lenguaje ensamblador 7 1 Ejemplo para la arquitectura x86 7 2 Ejemplo para el computador virtual POCA 7 3 Ejemplo para el computador virtual ARC 7 4 Ejemplo para el µC Intel 8051 7 5 Ejemplo para el Microchip PIC16F84 8 Vease tambien 9 Referencias 10 Bibliografia 11 Enlaces externosCaracteristicas EditarEl codigo escrito en lenguaje ensamblador posee una cierta dificultad de ser entendido ya que su estructura se acerca al lenguaje maquina es decir es un lenguaje de bajo nivel El lenguaje ensamblador es dificilmente portable es decir un codigo escrito para un microprocesador puede necesitar ser modificado para poder ser usado en otra maquina distinta Al cambiar a una maquina con arquitectura diferente generalmente es necesario reescribirlo completamente Los programas hechos por un programador experto en lenguaje ensamblador pueden ser mas rapidos y consumir menos recursos del sistema ej memoria RAM que el programa equivalente compilado desde un lenguaje de alto nivel Al programar cuidadosamente en lenguaje ensamblador se pueden crear programas que se ejecutan mas rapidamente y ocupan menos espacio que con lenguajes de alto nivel Conforme han evolucionado tanto los procesadores como los compiladores de lenguajes de alto nivel esta caracteristica del lenguaje ensamblador se ha vuelto cada vez menos significativa Es decir un compilador moderno de lenguaje de alto nivel puede generar codigo casi tan eficiente como su equivalente en lenguaje ensamblador 1 Con el lenguaje ensamblador se tiene un control muy preciso de las tareas realizadas por un microprocesador por lo que se pueden crear segmentos de codigo dificiles y o muy ineficientes de programar en un lenguaje de alto nivel ya que entre otras cosas en el lenguaje ensamblador se dispone de instrucciones del CPU que generalmente no estan disponibles en los lenguajes de alto nivel Programa ensamblador EditarArticulo principal Ensamblador Generalmente un programa ensamblador assembler en ingles moderno crea codigo objeto traduciendo instrucciones mnemonicas de lenguaje ensamblador en opcodes y resolviendo los nombres simbolicos para las localizaciones de memoria y otras entidades 2 El uso de referencias simbolicas es una caracteristica clave del lenguaje ensamblador evitando tediosos calculos y actualizaciones manuales de las direcciones despues de cada modificacion del programa La mayoria de los ensambladores tambien incluyen facilidades de macros para realizar sustitucion textual ej generar cortas secuencias de instrucciones como expansion en linea en vez de llamar a subrutinas Los ensambladores son generalmente mas simples de escribir que los compiladores para los lenguajes de alto nivel y han estado disponibles desde los anos 1950 Los ensambladores modernos especialmente para las arquitecturas basadas en RISC tales como MIPS Sun SPARC y HP PA RISC asi como tambien para el x86 64 optimizan la planificacion de instrucciones para explotar la segmentacion del CPU eficientemente En los compiladores para lenguajes de alto nivel son el ultimo paso antes de generar el codigo ejecutable Numero de pasos Editar Hay dos tipos de ensambladores basados en cuantos pasos a traves de la fuente son necesarios para producir el programa ejecutable Los ensambladores de un solo paso pasan a traves del codigo fuente una vez y asumen que todos los simbolos seran definidos antes de cualquier instruccion que los refiera Los ensambladores de dos pasos crean una tabla con todos los simbolos y sus valores en el primer paso despues usan la tabla en un segundo paso para generar codigo El ensamblador debe por lo menos poder determinar la longitud de cada instruccion en el primer paso para que puedan ser calculadas las direcciones de los simbolos La ventaja de un ensamblador de un solo paso es la velocidad que no es tan importante como lo fue en un momento dados los avances en velocidad y capacidades del computador La ventaja del ensamblador de dos pasos es que los simbolos pueden ser definidos dondequiera en el codigo fuente del programa Esto permite a los programas ser definidos de maneras mas logicas y mas significativas haciendo los programas de ensamblador de dos pasos mas faciles de leer y mantener 3 Ensambladores de alto nivel Editar Los mas sofisticados ensambladores de alto nivel proporcionan abstracciones del lenguaje tales como Estructuras de control avanzadas Declaraciones e invocaciones de procedimientos funciones de alto nivel Tipos de datos abstractos de alto nivel incluyendo las estructuras records uniones clases y conjuntos Procesamiento de macros sofisticado aunque esta disponible en los ensambladores ordinarios desde finales de los anos 1960 para el IBM S 360 entre otras maquinas Caracteristicas de programacion orientada a objetosUso del termino Editar Note que en el uso profesional normal el termino ensamblador es frecuentemente usado tanto para referirse al lenguaje ensamblador como tambien al programa ensamblador que convierte el codigo fuente escrito en el lenguaje ensamblador a codigo objeto que luego sera enlazado para producir lenguaje de maquina Las dos expresiones siguientes utilizan el termino ensamblador Lenguaje EditarEl lenguaje ensamblador refleja directamente la arquitectura y las instrucciones en lenguaje de maquina de la CPU y pueden ser muy diferentes de una arquitectura de CPU a otra Cada arquitectura de microprocesador tiene su propio lenguaje de maquina y en consecuencia su propio lenguaje ensamblador ya que este se encuentra muy ligado a la estructura del hardware para el cual se programa Los microprocesadores difieren en el tipo y numero de operaciones que soportan tambien pueden tener diferente cantidad de registros y distinta representacion de los tipos de datos en memoria Aunque la mayoria de los microprocesadores son capaces de cumplir esencialmente las mismas funciones la forma en que lo hacen difiere y los respectivos lenguajes ensamblador reflejan tal diferencia Instrucciones de CPU Editar La mayoria de las CPU tienen mas o menos los mismos grupos de instrucciones aunque no necesariamente tienen todas las instrucciones de cada grupo Las operaciones que se pueden realizar varian de una CPU a otra Una CPU particular puede tener instrucciones que no tenga otro y viceversa Los primeros microprocesadores de 8 bits no tenian operaciones para multiplicar o dividir numeros por ejemplo y habia que hacer subrutinas para realizar esas operaciones Otras CPU puede que no tengan operaciones de punto flotante y habria que hacer o conseguir bibliotecas que realicen esas operaciones Las instrucciones de la CPU pueden agruparse de acuerdo a su funcionalidad en Operaciones con enteros de 8 16 32 y 64 bits dependiendo de la arquitectura de la CPU en los sistemas muy viejos tambien de 12 18 24 36 y 48 bits Estas son operaciones realizadas por la Unidad aritmetico logica de la CPU Operaciones aritmeticas Como suma resta multiplicacion division modulo cambio de signo Operaciones booleanas Operaciones logicas bit a bit como AND OR XOR NOT Operaciones de bits Como desplazamiento o shift logico y rotaciones u Operadores a nivel de bits hacia la derecha o hacia la izquierda a traves del bit del acarreo o sin el ComparacionesOperaciones de mover datos Entre los registros y la memoria Aunque la instruccion se llama mover en la CPU mover datos significa en realidad copiar datos desde un origen a un destino sin que el dato desaparezca del origen Se pueden mover valores Desde un registro a otro Desde un registro a un lugar de la memoria Desde un lugar de la memoria a un registro Desde un lugar a otro de la memoria Un valor inmediato a un registro Un valor inmediato a un lugar de memoriaNota Un valor inmediato es una constante que se especifica en la misma microinstruccion Operaciones de pila stack en ingles PUSH escribe datos hacia el tope de la pila POP lee datos desde el tope de la pila Operaciones de entrada salida Son operaciones que mueven datos de un registro desde y hacia un puerto o de la memoria desde y hacia un puertoINPUT Lectura desde un puerto de entrada OUTPUT Escritura hacia un puerto de salidaOperaciones para el control del flujo del programa Llamadas y retornos de subrutinas Llamadas y retornos de interrupciones Saltos condicionales de acuerdo al resultado de una comparacion Saltos incondicionalesOperaciones con numeros reales El estandar para las operaciones con numeros reales en las CPU esta definido por el IEEE 754 Una CPU puede tener operaciones de punto flotante con numeros reales mediante el coprocesador numerico si lo hay como las siguientes Operaciones aritmeticas Suma resta multiplicacion division cambio de signo valor absoluto parte entera Operaciones trigonometricas Seno coseno tangente arcotangente Operaciones con logaritmos potencias y raices OtrasEl lenguaje ensamblador tiene mnemonicos para cada una de las instrucciones de la CPU en adicion a otros mnemonicos a ser procesados por el programa ensamblador como por ejemplo macros y otras sentencias en tiempo de ensamblado Ensamblado Editar La transformacion del lenguaje ensamblador en codigo maquina la realiza un programa ensamblador y la traduccion inversa la puede efectuar un desensamblador A diferencia de los lenguajes de alto nivel aqui hay usualmente una correspondencia 1 a 1 entre las instrucciones simples del ensamblador y el lenguaje de maquina Sin embargo en algunos casos un ensamblador puede proveer pseudo instrucciones que se expanden en un codigo de maquina mas extenso a fin de proveer la funcionalidad necesaria y simplificar la programacion Por ejemplo para un codigo maquina condicional como si X mayor o igual que un ensamblador puede utilizar una pseudoinstruccion al grupo haga si menor que y si 0 sobre el resultado de la condicion anterior Los Ensambladores mas completos tambien proveen un rico lenguaje de macros que se utiliza para generar codigo mas complejo y secuencias de datos Para el mismo procesador y el mismo conjunto de instrucciones de CPU diferentes programas ensambladores pueden tener cada uno de ellos variaciones y diferencias en el conjunto de mnemonicos o en la sintaxis de su lenguaje ensamblador Por ejemplo en un lenguaje ensamblador para la arquitectura x86 se puede expresar la instruccion para mover 5 al registro AL de la siguiente manera MOV AL 5 mientras que para otro ensamblador para la misma arquitectura se expresaria al reves MOV 5 AL Ambos lenguajes ensambladores harian exactamente lo mismo solo que esta expresado de manera diferente El primero usa la sintaxis de Intel mientras que el segundo usa la sintaxis de AT amp T El uso del ensamblador no resuelve definitivamente el problema de como programar un sistema basado en microprocesador de modo sencillo ya que para hacer un uso eficiente del mismo hay que conocer a fondo el microprocesador los registros de trabajo de que dispone la estructura de la memoria y muchas cosas mas referentes a su estructura basica de funcionamiento Ejemplos Editar Un programa escrito en lenguaje ensamblador consiste en una serie de instrucciones que corresponden al flujo de ordenes ejecutables por un microprocesador Por ejemplo en el lenguaje ensamblador para un procesador x86 La sentencia MOV AL 61hAsigna el valor hexadecimal 61 97 decimal al registro AL El programa ensamblador lee la sentencia de arriba y produce su equivalente binario en lenguaje de maquina Binario 10110000 01100001 hexadecimal B061 El mnemonico MOV es un codigo de operacion u opcode El opcode es seguido por una lista de argumentos o parametros completando una tipica instruccion de ensamblador En el ejemplo AL es un registro de 8 bits del procesador al cual se le asignara el valor hexadecimal 61 especificado El codigo de maquina generado por el ensamblador consiste de 2 bytes El primer byte contiene empaquetado la instruccion MOV y el codigo del registro hacia donde se va a mover el dato 1011 0000 01100001 Numero 61h en binario Registro AL Instruccion MOV En el segundo byte se especifica el numero 61h escrito en binario como 01100001 que se asignara al registro AL quedando la sentencia ejecutable como 10110000 01100001La cual puede ser entendida y ejecutada directamente por el procesador Diseno del lenguaje EditarElementos basicos Editar Hay un grado grande de diversidad en la manera en que los autores de los ensambladores categorizan las sentencias y en la nomenclatura que usan En particular algunos describen cualquier cosa como pseudo operacion pseudo Op con excepcion del mnemonico de maquina o del mnemonico extendido Un tipico lenguaje ensamblador consiste en 3 tipos de sentencias de instruccion que son usadas para definir las operaciones del programa Mnemonicos de opcode Secciones de datos Directivas de ensambladorMnemonicos de opcode y mnemonicos extendidos Editar A diferencia de las instrucciones sentencias de los lenguajes de alto nivel las instrucciones en el lenguaje ensamblador son generalmente muy simples Generalmente un mnemonico es un nombre simbolico para una sola instruccion en lenguaje de maquina ejecutable un opcode y hay por lo menos un mnemonico de opcode definido para cada instruccion en lenguaje de maquina Cada instruccion consiste tipicamente en una operacion u opcode mas cero o mas operandos La mayoria de las instrucciones refieren a un solo valor o a un par de valores Los operandos pueden ser inmediatos tipicamente valores de un byte codificados en la propia instruccion registros especificados en la instruccion implicitos o las direcciones de los datos localizados en otra parte de la memoria Esto esta determinado por la arquitectura subyacente del procesador el ensamblador simplemente refleja como trabaja esta arquitectura Los mnemonicos extendidos son frecuentemente usados para especificar una combinacion de un opcode con un operando especifico ej el ensamblador del System 360 usa a B como un mnemonico extendido para el BC con una mascara de 15 y NOP al BC con una mascara de 0 Los mnemonicos extendidos son frecuentemente usados para soportar usos especializados de instrucciones a menudo para propositos no obvios con respecto al nombre de la instruccion Por ejemplo muchos CPU no tienen una instruccion explicita de NOP No Operacion pero tienen instrucciones que puedan ser usadas para tal proposito En el CPU 8086 la instruccion XCHG AX AX intercambia el registro AX consigo mismo es usada para el NOP con NOP siendo un pseudo opcode para codificar la instruccion XCHG AX AX Algunos desensambladores reconocen esto y decodificaran la instruccion XCHG AX AX como NOP Similarmente los ensambladores de IBM para el System 360 usan los mnemonicos extendidos NOP y NOPR con las mascaras cero para BC y BCR Algunos ensambladores tambien soportan simples macroinstrucciones incorporadas que generan dos o mas instrucciones de maquina Por ejemplo con algunos ensambladores para el Z80 la instruccion LD HL BCgenera las instrucciones LD L C LD H B 4 LD HL BC es un pseudo opcode que en este caso simula ser una instruccion de 16 bits Cuando se expande se producen dos instrucciones de 8 bits que equivalen a la simulada de 16 bits Secciones de datos Editar Hay instrucciones usadas para definir elementos de datos para manejar datos y variables Definen el tipo de dato la longitud y la alineacion de los datos Estas instrucciones tambien pueden definir si los datos estan disponibles para programas exteriores programas ensamblados separadamente o solamente para el programa en el cual la seccion de datos esta definida Algunos ensambladores clasifican estas instruccion como pseudo instrucciones Directivas del ensamblador Editar Las directivas del ensamblador tambien llamadas pseudo opcodes pseudo operaciones o pseudo ops son instrucciones que son ejecutadas por un ensamblador en el tiempo de ensamblado no por la CPU en tiempo de ejecucion Pueden hacer al ensamblado del programa dependiente de parametros especificados por el programador de modo que un programa pueda ser ensamblado de diferentes maneras quizas para diversas aplicaciones Tambien pueden ser usadas para manipular la presentacion de un programa para hacerlo mas facil de leer y mantener Por ejemplo las directivas pudieran ser usadas para reservar areas de almacenamiento y opcionalmente para asignar su contenido inicial Los nombres de las directivas a menudo comienzan con un punto para distinguirlas de las instrucciones de maquina Los ensambladores simbolicos le permiten a los programadores asociar nombres arbitrarios etiquetas o simbolos a posiciones de memoria Usualmente cada constante y variable tiene un nombre para que las instrucciones puedan referir a esas ubicaciones por nombre asi promoviendo el codigo autodocumentado En el codigo ejecutable el nombre de cada subprograma es asociado a su punto de entrada asi que cualquier llamada a un subprograma puede usar su nombre Dentro de subprogramas a los destinos GOTO se le dan etiquetas Algunos ensambladores soportan simbolos locales que son lexicamente distintos de los simbolos normales ej el uso de 10 como un destino GOTO La mayoria de los ensambladores proporcionan un manejo flexible de simbolos permitiendo a los programadores manejar diversos espacios de nombres calcular automaticamente offsets dentro de estructuras de datos y asignar etiquetas que refieren a valores literales o al resultado de calculos simples realizados por el ensamblador Las etiquetas tambien pueden ser usadas para inicializar constantes y variables con direcciones relocalizables Los lenguajes ensambladores como la mayoria de los otros lenguajes de computador permiten que sean anadidos comentarios al codigo fuente que son ignorados por el programa ensamblador El buen uso de los comentarios es aun mas importante con codigo ensamblador que con lenguajes de alto nivel pues el significado y el proposito de una secuencia de instrucciones puede ser mas dificil de entender a partir del codigo en si mismo El uso sabio de estas facilidades puede simplificar significativamente los problemas de codificar y mantener el codigo de bajo nivel El codigo fuente de lenguaje ensamblador crudo generado por compiladores o desensambladores codigo sin ningun comentario ni simbolos con algun sentido ni definiciones de datos es muy dificil de leer cuando deben hacerse cambios Macros Editar Muchos ensambladores soportan macros predefinidas y otros soportan macros definidas y repetidamente redefinibles por el programador que implican secuencias de lineas del texto en las cuales las variables y las constantes estan embebidas Esta secuencia de lineas de texto puede incluir opcodes o directivas Una vez una macro se define su nombre se puede usar en lugar de un mnemonico Cuando el ensamblador procesa tal sentencia reemplaza la sentencia por las lineas del texto asociadas a esa macro Entonces las procesa como si hubieran existido en el archivo del codigo fuente original incluyendo en algunos ensambladores la expansion de cualquier macro que exista en el texto de reemplazo Puesto que las macros pueden tener nombres cortos pero se expanden a varias o de hecho muchas lineas de codigo pueden usarse para hacer que los programas en lenguaje ensamblador parezcan ser mucho mas cortos requiriendo menos lineas de codigo fuente como sucede con los lenguajes de alto nivel Tambien se pueden usar para anadir niveles de estructura mas altos a los programas ensamblador opcionalmente introducen codigo de depuracion embebido via parametros y otras caracteristicas similares Muchos ensambladores tienen macros incorporadas o predefinidas para las llamadas de sistema y otras secuencias especiales de codigo tales como la generacion y el almacenamiento de los datos realizados a traves de avanzadas operaciones bitwise y operaciones booleanas usadas en juegos software de seguridad gestion de datos y criptografia Los macro ensambladores a menudo permiten a las macros tomar parametros Algunos ensambladores incluyen lenguajes macro sofisticados incorporando elementos de lenguajes de alto nivel tales como parametros opcionales variables simbolicas condiciones manipulaciones de strings operaciones aritmeticas todos usables durante la ejecucion de una macro dada y permitiendo a las macros guardar el contexto o intercambiar informacion Asi una macro puede generar un gran numero de instrucciones o definiciones de datos en lenguaje ensamblador basadas en los argumentos de la macro Esto se podria usar para generar por ejemplo estructuras de datos de estilo de record o bucles desenrollados o podria generar algoritmos enteros basados en parametros complejos Una organizacion usando lenguaje ensamblador que ha sido fuertemente extendido usando tal suite de macros puede ser considerada que se esta trabajando en un lenguaje de alto nivel puesto que tales programadores no estan trabajando con los elementos conceptuales de mas bajo nivel del computador Las macros se usaron para personalizar sistemas de software de gran escala para clientes especificos en la era del mainframe Tambien se emplearon macros por los usuarios mismos para satisfacer las necesidades de sus organizaciones haciendo versiones especificas de los sistemas operativos del fabricante Esto fue hecho por ejemplo por los programadores de sistema que trabajaban con el Conversational Monitor System Virtual Machine CMS VM de IBM y con los complementos real time transaction processing de IBM CICS Customer Information Control System el airline financial system que comenzo en los anos 1970 y todavia corre con muchos sistemas de reservaciones computarizados CRS y sistemas de tarjeta de credito de hoy Tambien es posible usar solamente las habilidades de procesamiento de macros de un ensamblador para generar codigo escrito en lenguajes completamente diferentes Por ejemplo para generar una version de un programa en COBOL usando un programa macro ensamblador puro conteniendo lineas de codigo COBOL dentro de operadores de tiempo ensamblaje dando instrucciones al ensamblador para generar codigo arbitrario Esto era porque como en los anos 1970 fue observado el concepto de procesamiento de macro es independiente del concepto de ensamblaje siendo el anterior en terminos modernos mas un procesamiento de textos que una generacion de codigo objeto El concepto de procesamiento de macro aparecio y aparece en el lenguaje de programacion C que soporta instrucciones de preprocesador de fijar variables y hace pruebas condicionales en sus valores Observe que a diferencia de ciertos macroprocesadores previos dentro de los ensambladores el preprocesador de C no es Turing completo porque carecia de la capacidad de bucle o go to esto ultimo permitiendo a los programas hacer bucles A pesar del poder del procesamiento macro este dejo de usarse en muchos lenguajes de alto nivel una importante excepcion es C C pero persistio en los ensambladores Esto era porque muchos programadores estaban bastante confundidos por la sustitucion de parametros macro y no distinguian la diferencia entre procesamiento macro el ensamblaje y la ejecucion La sustitucion de parametros macro es estrictamente por nombre en el tiempo de procesamiento macro el valor de un parametro es sustituido textualmente por su nombre La clase mas famosa de Error de software resultantes era el uso de un parametro que en si mismo era una expresion y no un nombre primario cuando el escritor macro esperaba un nombre En el macro foo macro a load a bla intencion era que la rutina que llama proporcionaria el nombre de una variable y la variable o constante global b seria usada para multiplicar a a Si foo se llama con el parametro a c ocurre la expansion macro load a c b Para evitar cualquier posible ambiguedad los usuarios de macro procesadores pueden encerrar en parentesis los parametros formales dentro de las definiciones de macros o las rutinas que llaman pueden envolver en parentesis los parametos de entrada 5 Asi el macro correcto con los parentesis seria foo macro a load a by su expansion daria como resultado load a c bEl PL I y el C C ofrecen macros pero esta facilidad solo puede manipular texto Por otra parte los lenguajes homoiconicos tales como Lisp Prolog y Forth retienen el poder de los macros de lenguaje ensamblador porque pueden manipular su propio codigo como datos Soporte para programacion estructurada Editar Algunos ensambladores han incorporado elementos de programacion estructurada para codificar el flujo de la ejecucion El ejemplo mas temprano de este acercamiento estaba en el Concept 14 macro set originalmente propuesto por el Dr H D Mills marzo de 1970 e implementado por Marvin Kessler en la Federal Systems Division de IBM que extendio el macro ensamblador del S 360 con bloques de control de flujo IF ELSE ENDIF y similares 6 Esto era una manera de reducir o eliminar el uso de operaciones GOTO en el codigo en lenguaje ensamblador uno de los principales factores que causaban codigo espagueti en el lenguaje ensamblador Este acercamiento fue ampliamente aceptado a principios de los anos 1980 los ultimos dias del uso de lenguaje ensamblador en gran escala Un curioso diseno fue A natural un ensamblador orientado a la corriente stream oriented para los procesadores 8080 Z80 cita requerida de Whitesmiths Ltd desarrolladores del sistema operativo Idris similar al Unix y lo que fue reportado como el primer compilador C comercial El lenguaje fue clasificado como un ensamblador porque trabajaba con elementos de maquina crudos tales como opcodes registros y referencias de memoria pero incorporaba una sintaxis de expresion para indicar el orden de ejecucion Los parentesis y otros simbolos especiales junto con construcciones de programacion estructurada orientadas a bloques controlaban la secuencia de las instrucciones generadas A natural fue construido como el lenguaje objeto de un compilador C en vez de la codificacion manual pero su sintaxis logica gano algunos seguidores Ha habido poca demanda aparente para ensambladores mas sofisticados debido a la declinacion del desarrollo de lenguaje ensamblador de larga escala 7 A pesar de eso todavia se estan desarrollando y aplicando en casos donde las limitaciones de recursos o las particularidades en la arquitectura de sistema objetivo previenen el efectivo uso de lenguajes de alto nivel 8 Uso del lenguaje ensamblador EditarPerspectiva historica Editar Los lenguajes ensambladores fueron primero desarrollados en los anos 1950 cuando fueron referidos como lenguajes de programacion de segunda generacion Por ejemplo el SOAP Symbolic Optimal Assembly Program era un lenguaje ensamblador de 1957 para el computador IBM 650 Los lenguajes ensambladores eliminaron mucha de la propension a errores y del consumo de tiempo de la programacion de los lenguajes de primera generacion que se necesitaba con los primeros computadores liberando a los programadores del tedio tal como recordar codigos numericos y calculo de direcciones Una vez fueron ampliamente usados para todo tipo de programacion Sin embargo por los anos 1980 1990 en los microcomputadores su uso habia sido en gran parte suplantado por los lenguajes de alto nivel cita requerida en la busqueda de una mejorada productividad en programacion Hoy en dia aunque el lenguaje ensamblador es casi siempre manejado y generado por los compiladores todavia se usa para la manipulacion directa del hardware acceso a instrucciones especializadas del procesador o para resolver problemas de desempeno critico Los usos tipicos son controladores manejadores drivers de dispositivo sistemas embebidos de bajo nivel y sistemas de tiempo real Historicamente un gran numero de programas han sido escritos enteramente en lenguaje ensamblador Los sistemas operativos fueron casi exclusivamente escritos en lenguaje ensamblador hasta la aceptacion amplia del lenguaje de programacion C en los anos 1970 y principios de los 1980 Tambien muchas aplicaciones comerciales fueron escritas en lenguaje ensamblador incluyendo una gran cantidad del software escrito por grandes corporaciones para mainframes de IBM Los lenguajes COBOL y FORTRAN eventualmente desplazaron mucho de este trabajo aunque un numero de organizaciones grandes conservaran las infraestructuras de aplicaciones en lenguaje ensamblador hasta bien entrados los anos 1990 La mayoria de los primeros microcomputadores confiaron en el lenguaje ensamblador codificado a mano incluyendo la mayoria de los sistemas operativos y de las aplicaciones grandes Esto era porque estos sistemas tenian limitaciones severas de recursos impusieron idiosincraticas arquitecturas de memoria y de pantalla y proporcionaron servicios de sistema limitados y con errores Quizas mas importante era la falta de compiladores de primera clase de lenguajes de alto nivel adecuados para el uso en el microcomputador Un factor psicologico tambien pudo haber jugado un papel la primera generacion de programadores de los microcomputadores conservo una actitud de aficionado de alambres y alicates En un contexto mas comercial las mas grandes razones para usar el lenguaje ensamblador era hacer programas con minimo tamano minima sobrecarga mayor velocidad y confiabilidad Los tipicos ejemplos de programas grandes en lenguaje ensamblador de ese tiempo son los sistemas operativos IBM PC DOS y aplicaciones tempranas tales como la hoja de calculo Lotus 1 2 3 y casi todos los juegos populares para la familia Atari 800 de computadores personales Incluso en los anos 1990 la mayoria de los videojuegos de consola fueron escritos en ensamblador incluyendo la mayoria de los juegos para la Mega Drive Genesis y el Super Nintendo Entertainment System cita requerida Segun algunos insiders de la industria el lenguaje ensamblador era el mejor lenguaje de programacion a usar para obtener el mejor desempeno del Sega Saturn una consola para la cual era notoriamente desafiante desarrollar y programar juegos 9 El popular juego de arcade NBA Jam 1993 es otro ejemplo El ensamblador ha sido por largo trecho el lenguaje de desarrollo primario en los computadores hogarenos Commodore 64 Atari ST asi como el ZX Spectrum Esto fue asi en gran parte porque los dialectos del BASIC en estos sistemas ofrecieron insuficiente velocidad de ejecucion asi como insuficientes caracteristicas para aprovechar completamente el hardware disponible Algunos sistemas mas notablemente el Amiga incluso tienen IDEs con caracteristicas de depuracion y macros altamente avanzados tales como el freeware ASM One assembler comparable a las del Microsoft Visual Studio el ASM Uno precede al Microsoft Visual Studio El ensamblador para el VIC 20 fue escrito por Don French y publicado por French Silk Con 1639 bytes de longitud su autor cree que es el mas pequeno ensamblador simbolico jamas escrito El ensamblador soportaba el direccionamiento simbolico usual y la definicion de cadenas de caracteres o cadenas hexadecimales Tambien permitia expresiones de direcciones que podian combinarse con las operaciones de adicion sustraccion multiplicacion division AND logico OR logico y exponenciacion 10 Uso actual Editar Siempre ha habido debates sobre la utilidad y el desempeno del lenguaje ensamblador relativo a lenguajes de alto nivel El lenguaje ensamblador tiene nichos especificos donde es importante ver abajo Pero en general los modernos compiladores de optimizacion para traducir lenguajes de alto nivel en codigo pueden correr tan rapidamente como el lenguaje ensamblador escrito a mano a pesar de los contraejemplos que pueden ser encontrados 11 12 13 La complejidad de los procesadores modernos y del subsistema de memoria hace la optimizacion efectiva cada vez mas dificil para los compiladores asi como para los programadores en ensamblador 14 15 Adicionalmente y para la consternacion de los amantes de la eficiencia el desempeno cada vez mayor del procesador ha significado que la mayoria de los CPU esten desocupados la mayor parte del tiempo con retardos causados por embotellamientos predecibles tales como operaciones de entrada salida y paginacion de memoria Esto ha hecho que la velocidad de ejecucion cruda del codigo no sea un problema para muchos programadores Hay algunas situaciones en las cuales los profesionales pudieran elegir utilizar el lenguaje ensamblador Por ejemplo cuando Es requerido un ejecutable binario independiente stand alone es decir uno que deba ejecutarse sin recursos a componentes de tiempo de ejecucion o a bibliotecas asociadas con un lenguaje de alto nivel esta es quizas la situacion mas comun Son programas empotrados que solo almacenan una pequena cantidad de memoria y el dispositivo esta dirigido para hacer tareas para un simple proposito Ejemplos consisten en telefonos sistemas de combustible e ignicion para automoviles sistemas de control del aire acondicionado sistemas de seguridad y sensores Interactuando directamente con el hardware por ejemplo en controladores drivers de dispositivo y manejadores de interrupcion Usando instrucciones especificas del procesador no explotadas o disponibles por el compilador Un ejemplo comun es la instruccion de rotacion bitwise en el nucleo de muchos algoritmos de cifrado Creando funciones vectorizadas para programas en lenguajes de alto nivel como C En el lenguaje de alto nivel esto es a veces ayudado por funciones intrinsecas del compilador que mapean directamente a los mnemonicos del SIMD pero sin embargo resulta en una conversion de ensamblador de uno a uno para un procesador de vector asociado Es requerida la optimizacion extrema ej en un bucle interno en un algoritmo intensivo en el uso del procesador Los programadores de juegos toman ventaja de las habilidades de las caracteristicas del hardware en los sistemas permitiendo a los juegos correr mas rapidamente Tambien las grandes simulaciones cientificas requieren algoritmos altamente optimizados ej algebra lineal con BLAS o la transformada de coseno discreta ej la version SIMD en ensamblador del x264 16 una biblioteca para codificar streams de video Un sistema con severas limitaciones de recursos ej un sistema empotrado debe ser codificado a mano para maximizar el uso de los limitados recursos pero esto esta llegando a ser menos comun a medida que el precio del procesador decrece y el desempeno mejora No existe ningun lenguaje de alto nivel en un procesador nuevo o especializado Escribiendo programas de tiempo real que necesitan sincronizacion y respuestas precisas tales como sistemas de navegacion de vuelo y equipo medico Por ejemplo en un sistema fly by wire vuelo por mandos electricos la telemetria debe ser interpretada y hay que actuar dentro de limitaciones estrictas de tiempo Tales sistemas deben eliminar fuentes de retrasos impredecibles que pueden ser creados por algunos lenguajes interpretados recoleccion de basura automatica operaciones de paginacion o multitarea apropiativa Sin embargo algunos lenguajes de alto nivel incorporan componentes de tiempo de ejecucion e interfaces de sistema operativo que pueden introducir tales retrasos Elegir el ensamblador o lenguajes de bajo nivel para tales sistemas da a los programadores mayor visibilidad y control sobre los detalles del procesamiento Es requerido control total sobre el ambiente en situaciones de seguridad extremadamente alta donde nada puede darse por sentado Se escriben virus de computadora bootloaders ciertos controladores manejadores de dispositivo u otros elementos muy cerca del hardware o al sistema operativo de bajo nivel Se escriben simuladores del conjunto de instrucciones para monitoreo trazado y depuracion de errores donde la sobrecarga adicional es mantenida al minimo Se hace ingenieria inversa en binarios existentes que pueden o no haber sido escritos originalmente en un lenguaje de alto nivel por ejemplo al crackear la proteccion anticopia del software propietario Se hace ingenieria inversa y modificacion de video juegos tambien denominado ROM hacking que es posible por medio de varios metodos El mas ampliamente implementado es alterando el codigo del programa a nivel de lenguaje ensamblador Se escribe codigo automodificable tambien conocido como polimorfico algo para lo que el lenguaje ensamblador se presta bien Se escriben juegos y otros softwares para calculadoras graficas 17 Se escribe software compilador que genera codigo ensamblador y por lo tanto los desarrolladores deben ser programadores de lenguaje ensamblador Se escriben algoritmos criptograficos que siempre deben tomar estrictamente el mismo tiempo para ejecutar previniendo ataques de tiempo Sin embargo el lenguaje ensamblador es todavia ensenado en la mayoria de los programas de ciencias de la computacion e ingenieria electronica Aunque hoy en dia pocos programadores trabajan regularmente con el lenguaje ensamblador como una herramienta los conceptos fundamentales continuan siendo muy importantes Tales topicos fundamentales como aritmetica binaria asignacion de memoria procesamiento del stack codificacion de conjunto de caracteres procesamiento de interrupciones y diseno de compiladores serian duros de estudiar en detalle sin la comprension de como el computador opera a nivel del hardware Puesto que el comportamiento del computador es fundamentalmente definido por su conjunto de instrucciones la manera logica de aprender tales conceptos es estudiar un lenguaje ensamblador La mayoria de los computadores modernos tienen un conjunto de instrucciones similares Por lo tanto estudiar un solo lenguaje ensamblador es suficiente para aprender i los conceptos basicos ii reconocer situaciones donde el uso de lenguaje ensamblador puede ser apropiado y iii ver como el codigo ejecutable eficiente puede ser creado por los lenguajes de alto nivel 18 Aplicaciones tipicas Editar El lenguaje ensamblador hard coded es tipicamente usado en el ROM de arranque del sistema BIOS en los sistemas compatible IBM PC Este codigo de bajo nivel es usado entre otras cosas para inicializar y probar el hardware del sistema antes de cargar el sistema operativo y esta almacenado en el ROM Una vez que ha tomado lugar un cierto nivel de inicializacion del hardware la ejecucion se transfiere a otro codigo tipicamente escrito en lenguajes de alto nivel pero el codigo corriendo inmediatamente despues de que es aplicada la energia usualmente esta escrito en lenguaje ensamblador Lo mismo es cierto para los boot loaders Muchos compiladores traducen lenguajes de alto nivel a lenguaje ensamblador primero antes de la compilacion completa permitiendo que el codigo en ensamblador sea visto para propositos de depuracion y optimizacion Lenguajes de relativo bajo nivel como C con frecuencia proveen sintaxis especial para empotrar lenguaje ensamblador en cada plataforma de hardware El codigo portable del sistema entonces puede usar estos componentes especificos a un procesador a traves de una interface uniforme El lenguaje ensamblador tambien es valioso en ingenieria inversa puesto que muchos programas solamente son distribuidos en una forma de codigo de maquina El codigo de maquina es usualmente facil de trasladar hacia lenguaje ensamblador para luego ser cuidadosamente examinado en esta forma pero es muy dificil de trasladar hacia un lenguaje de alto nivel Herramientas como Interactive Disassembler hacen uso extenso del desensamblador para tales propositos Un nicho que hace uso del lenguaje ensamblador es el demoscene Ciertas competiciones requieren a los concursantes restringir sus creaciones a un muy pequeno tamano ej 256 bytes 1 KB 4 KB o 64 KB y el lenguaje ensamblador es el lenguaje de preferencia para alcanzar este objetivo 19 Cuando los recursos son una preocupacion es una necesidad la codificacion en ensamblador especialmente en sistemas constrenidos por el procesamiento del CPU como los primeros modelos del Amiga y el Commodore 64 El codigo optimizado en ensamblador es escrito a mano por los programadores en un intento de minimizar el numero de ciclos de CPU usados Las limitaciones del CPU son tan grandes que cada ciclo cuenta Usar tales metodos ha habilitado a sistemas como el Commodore 64 para producir graficos en 3D en tiempo real con efectos avanzados una hazana que puede ser considerada improbable o incluso imposible para un sistema con un procesador de 0 99 MHz cita requerida Detalles adicionales EditarPara un determinado computador personal mainframe sistema empotrado y consola de juegos tanto del pasado como del presente ha sido escrito al menos uno y posiblemente docenas de ensambladores Para algunos ejemplos vea la lista de ensambladores En los sistemas Unix el ensamblador es llamado tradicionalmente as aunque no es un simple cuerpo de codigo siendo tipicamente escrito uno nuevo por cada port Un numero de variantes de Unix usan el GASDentro de los grupos de procesadores cada ensamblador tiene su propio dialecto A veces algunos ensambladores pueden leer el dialecto de otro por ejemplo TASM puede leer el viejo codigo del MASM pero no al reves FASM y NASM tienen una sintaxis similar pero cada uno soporta diferentes macros que pueden ser dificil de trasladar de uno al otro Las cosas basicas son siempre las mismas pero las caracteristicas avanzadas seran diferentes 20 Tambien los lenguajes ensambladores a veces pueden ser portables a traves de diferentes sistemas operativos en el mismo tipo de CPU Las convenciones de llamadas entre los sistemas operativos con frecuencia difieren ligeramente o en nada y con cuidado es posible ganar portabilidad en el lenguaje ensamblador usualmente al enlazar con una biblioteca de lenguaje C que no cambia entre sistemas operativos Un simulador de conjunto de instrucciones que idealmente seria escrito en lenguaje ensamblador puede en teoria procesar el codigo objeto binario de cualquier ensamblador para lograr la portabilidad incluso a traves de plataformas con una sobrecargue no mayor que la de un interpretador de bytecode tipico Esto es esencialmente lo que logra el microcodigo cuando una plataforma de hardware cambia internamente Por ejemplo muchas cosas en libc dependen del preprocesador para hacer al programa antes de compilar cosas que son especificas del sistema operativo o especificas del C De hecho algunas funciones y simbolos ni siquiera estan garantizados que existan fuera del preprocesador Peor aun el tamano y el orden de los campos de las estructuras tanto como el tamano de ciertas typedefs como off t no estan disponibles en lenguaje ensamblador sin la ayuda de un script de configuracion y difieren incluso entre versiones de Linux haciendo imposible portar llamadas de funciones en libc diferentes de los que toman simples enteros o punteros como parametros Para manejar estos problemas el proyecto FASMLIB provee una biblioteca de lenguaje ensamblador portable para las plataformas Win32 y Linux pero todavia esta muy incompleta 21 Algunos lenguajes de muy alto nivel como C y Borland Pascal soportan ensamblado en linea donde relativamente secciones cortas de codigo en ensamblador puede ser empotradas dentro del codigo del lenguaje de alto nivel El lenguaje Forth comunmente contiene un ensamblador usado para codificar palabras La mayoria de la gente usa un emulador para depurar sus programas en lenguaje ensamblador Ejemplos de lenguaje ensamblador EditarEjemplo para la arquitectura x86 Editar El siguiente es un ejemplo del programa clasico Hola mundo escrito para la arquitectura de procesador x86 bajo el sistema operativo DOS Programa que imprime un string en la pantalla model small modelo de memoria stack segmento del stack data segmento de datos Cadena1 DB Hola Mundo string a imprimir finalizado en code segmento del codigo Inicio del programa programa inicia el segmento de datos MOV AX data carga en AX la direccion del segmento de datos MOV DS AX mueve la direccion al registro de segmento por medio de AX Imprime un string en pantalla MOV DX offset Cadena1 mueve a DX la direccion del string a imprimir MOV AH 9 AH codigo para indicar al MS DOS que imprima en la pantalla el string en DS DX INT 21 h llamada al MS DOS para ejecutar la funcion en este caso especificada en AH Finaliza el programa INT 20 h llamada al MS DOS para finalizar el programa end programa Ejemplo para el computador virtual POCA Editar Una seleccion de instrucciones para una computadora virtual 22 con las correspondientes direcciones de memoria en las que se ubicaran las instrucciones Estas direcciones NO son estaticas Cada instruccion se acompana del codigo en lenguaje ensamblador generado codigo objeto que coincide con la arquitectura de computador virtual o conjunto de instrucciones ISA Dir Etiqueta Instruccion Codigo maquina 23 begin org 2048a start equ 30002048 ld length r12064 be done 00000010 10000000 00000000 000001102068 addcc r1 4 r1 10000010 10000000 01111111 111111002072 addcc r1 r2 r4 10001000 10000000 01000000 000000102076 ld r4 r5 11001010 00000001 00000000 000000002080 ba loop 00010000 10111111 11111111 111110112084 addcc r3 r5 r3 10000110 10000000 11000000 000001012088 done jmpl r15 4 r0 10000001 11000011 11100000 000001002092 length 20 00000000 00000000 00000000 000101002096 address a start 00000000 00000000 00001011 10111000 org a start3000 a Ejemplo para el computador virtual ARC Editar ARC es un subconjunto del modelo de arquitectura basado en el procesador SPARC ARC A RISC Computer contiene la mayoria de las caracteristicasimportantes de la arquitectura SPARC Direccion Etiqueta Instruccion Comentarios begin org 2048a start equ 3000 Direccion de memoria del arreglo comienza en 30002048 ld lenght r1 Se establece la longitud del arreglo en el registro2052 ld address r2 Direccion del arreglo a2056 anddcc r3 r0 r3 Se establece con cero la suma parcial2060 loop anddcc r1 r1 r0 Verifico si r1 tiene elementos restantes2064 be done2068 addcc r1 4 r1 Decremento el tamano del arreglo2072 ld r1 r2 r4 Cargo el proximo elemento en r42076 addcc r3 r4 r3 Actualizo la suma parcial en r32080 ba loop Vuelve a verificar la condicion de corte2084 done jmpl r15 4 r0 Retorno a la rutina principal2088 lenght 20 Tamano del arreglo en 20 bytes 5 numeros2092 address a start org a start Comienzo del arreglo aa 2515 20 3515 end Fin del programa Ejemplo para el µC Intel 8051 Editar Codigo en lenguaje ensamblador para µC Intel 80C51 ORG 8030 H include T05SEG SETB TR0 JNB uSEG T05SEG esta subrutina es utilizada CLR TR0 para realizar una cuenta de CPL uSEG 0 5 segundos mediante la MOV R1 DPL interrupcion del timer 0 INVOKE MOV R2 DPH CJNE R2 07 H T05SEG CJNE R1 78 H T05SEG MOV DPTR 0 RET Ejemplo para el Microchip PIC16F84 Editar Codigo en lenguaje ensamblador para el microcontrolador 16F84 de Microchip ORG 0 Inicio bcf STATUS RP0 clrf PORTB movlw 0xFF movwf PORTA bsf STATUS RP0 Principal movf PORTA W movwf Contador movf Contador F btfsc STATUS Z goto PuntoDecimal sublw d 9 btfss STATUS C ENDVease tambien EditarLenguaje ensamblador x86 Anexo Listados de instrucciones x86 Ensamblador Macro ensamblador Ensamblador de alto nivel Desensamblador Compilador Decompilador Interprete informatica Depurador Lenguaje de alto nivel Lenguaje de bajo nivel Lenguaje de maquina Conjunto de instrucciones Tipos de datos maquina Little man computerEnsambladores Comparacion de ensambladores High Level Assembly Netwide Assembler Flat assembler GNU Assembler Microsoft Macro Assembler RosASM A86 y A386 assemblers Turbo Assembler GNU toolchainDesensambladores Interactive DisassemblerDepuradores SoftICE GNU Debugger OllyDbg Valgrind RosASM A86 y A386 assemblers Data Display DebuggerOtrosSistemas operativos escritos completamente en assembler MenuetOS KolibriOS BareMetal OSReferencias Editar DSP C versus Assembly Steven W Smith Ph D 2011 David Salomon 1993 Assemblers and Loaders Beck Leland L 1996 2 System Software An Introduction to Systems Programming Addison Wesley http www z80 de z80 z80code htm Macros C C MSDN Library for Visual Studio 2008 Microsoft Corp Consultado el 22 de junio de 2010 Concept 14 Macros MVS Software Consultado el 25 de mayo de 2009 Answers com assembly language Definition and Much More from Answers com Consultado el 19 de junio de 2008 NESHLA The High Level Open Source 6502 Assembler for the Nintendo Entertainment System Eidolon s Inn SegaBase Saturn Archivado desde el original el 13 de julio de 2008 Consultado el 25 de julio de 2008 Jim Lawless 21 de mayo de 2004 Speaking with Don French The Man Behind the French Silk Assembler Tools Archivado desde el original el 21 de agosto de 2008 Consultado el 25 de julio de 2008 Writing the Fastest Code by Hand for Fun A Human Computer Keeps Speeding Up Chips New York Times John Markoff 28 de noviembre de 2005 Consultado el 4 de marzo de 2010 Bit field badness hardwarebug org 30 de enero de 2010 Archivado desde el original el 5 de febrero de 2010 Consultado el 4 de marzo de 2010 GCC makes a mess hardwarebug org 13 de mayo de 2009 Archivado desde el original el 16 de marzo de 2010 Consultado el 4 de marzo de 2010 Randall Hyde The Great Debate Archivado desde el original el 16 de junio de 2008 Consultado el 3 de julio de 2008 Code sourcery fails again hardwarebug org 30 de enero de 2010 Archivado desde el original el 2 de abril de 2010 Consultado el 4 de marzo de 2010 x264 git common x86 dct 32 asm git videolan org 29 de septiembre de 2010 Archivado desde el original el 4 de marzo de 2012 Consultado el 29 de septiembre de 2010 68K Programming in Fargo II Consultado el 3 de julio de 2008 Hyde Randall 30 de septiembre de 1996 Foreword Why would anyone learn this stuff op cit Archivado desde el original el 22 de febrero de 2010 Consultado el 5 de marzo de 2010 256bytes demos archives Consultado el 3 de julio de 2008 Randall Hyde Which Assembler is the Best Archivado desde el original el 18 de octubre de 2007 Consultado el 19 de octubre de 2007 vid FASMLIB Features Consultado el 19 de octubre de 2007 Principles of Computer Architecture POCA ARCTools computadora virtual disponible para descarga y ejecucion del codigo acceso el 24 de agosto de 2005 Murdocca Miles J y Heuring Vincent P Principles of Computer Architecture 2000 Prentice Hall ISBN 0 201 43664 7Bibliografia EditarDominic Sweetman See MIPS Run Morgan Kaufmann Publishers 1999 ISBN 1 55860 410 3 Robert Britton MIPS Assembly Language Programming Prentice Hall 2003 ISBN 0 13 142044 5 John Waldron Introduction to RISC Assembly Language Programming Addison Wesley 1998 ISBN 0 201 39828 1 ASM Community Book An online book full of helpful ASM info tutorials and code examples by the ASM Community Jonathan Bartlett Programming from the Ground Up Bartlett Publishing 2004 ISBN 0 9752838 4 7Also available online as PDF Archivado el 6 de febrero de 2009 en Wayback Machine Paul Carter PC Assembly Language Free ebook 2001 Website Jeff Duntemann Assembly Language Step by Step Wiley 2000 ISBN 0 471 37523 3 Randall Hyde The Art of Assembly Language No Starch Press 2003 ISBN 1 886411 97 2Draft versions available online as PDF and HTML Peter Norton John Socha Peter Norton s Assembly Language Book for the IBM PC Brady Books NY 1986 Michael Singer PDP 11 Assembler Language Programming and Machine Organization John Wiley amp Sons NY 1980 Principios de arquitectura de computadoras Miles J Murdocca Vincent P HeuringEnlaces externos Editar Wikilibros alberga un libro o manual sobre Programacion en lenguaje ensamblador The Art of Assembly Language Programming Computer Books us Online Assembly Language Brooks PC Assembly Tutorial using NASM and GCC by Paul Carter Programming from the Ground Up by Jonathan Bartlett The ASM Book by the ASM Community Inline ASM modulo Perl en CPAN para programar en lenguaje ensamblador dentro de programas Perl en ingles Ejemplos practicos de ensamblador en GNU Linux Datos Q165436 Multimedia Assemblers Libros y manuales Programacion en lenguaje ensambladorObtenido de https es wikipedia org w index php title Lenguaje ensamblador amp oldid 137548033, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos