De Wikipedia, la enciclopedia libre
Ir a navegaciónSaltar a buscar

En programación de computadoras , el lenguaje ensamblador (o lenguaje ensamblador ), [1] a veces abreviado asm , es cualquier lenguaje de programación de bajo nivel en el que existe una correspondencia muy fuerte entre las instrucciones en el lenguaje y las instrucciones del código máquina de la arquitectura . [2] Debido a que el ensamblaje depende de las instrucciones del código de máquina, cada lenguaje ensamblador está diseñado para exactamente una arquitectura de computadora específica. El lenguaje ensamblador también puede denominarse código máquina simbólico . [3] [4]

El código de ensamblaje se convierte en código de máquina ejecutable mediante un programa de utilidad denominado ensamblador . El proceso de conversión se denomina ensamblaje , como ensamblar el código fuente . El lenguaje ensamblador generalmente tiene una instrucción por instrucción de máquina (1: 1), pero las constantes, comentarios , directivas de ensamblador , [5] etiquetas simbólicas de programas y ubicaciones de memoria , y macros [6] [1] generalmente también son compatibles.

El término "ensamblador" se atribuye generalmente a Wilkes , Wheeler y Gill en su libro de 1951 La preparación de programas para una computadora digital electrónica , [7] quienes, sin embargo, usaron el término para significar "un programa que ensambla otro programa que consta de varios secciones en un solo programa ". [8]

Cada lenguaje ensamblador es específico de una arquitectura de computadora en particular y, a veces, de un sistema operativo . [9] Sin embargo, algunos lenguajes ensambladores no proporcionan una sintaxis específica para las llamadas al sistema operativo, y la mayoría de los lenguajes ensambladores se pueden usar universalmente con cualquier sistema operativo, ya que el lenguaje proporciona acceso a todas las capacidades reales del procesador , sobre las cuales todos los sistemas llaman los mecanismos descansan en última instancia. A diferencia de los lenguajes ensambladores, la mayoría de los lenguajes de programación de alto nivel son generalmente portables a través de múltiples arquitecturas, pero requieren interpretación o compilación., una tarea mucho más complicada que el montaje.

El paso computacional cuando un ensamblador está procesando un programa se llama tiempo de ensamblaje .

Sintaxis del lenguaje ensamblador

El lenguaje ensamblador usa un mnemónico para representar cada instrucción de máquina de bajo nivel o código de operación , típicamente también cada registro arquitectónico , bandera , etc. Muchas operaciones requieren uno o más operandos para formar una instrucción completa. La mayoría de los ensambladores permiten constantes, registros y etiquetas con nombre para ubicaciones de programa y memoria, y pueden calcular expresiones para operandos. Por lo tanto, los programadores se liberan de los tediosos cálculos repetitivos y los programas en ensamblador son mucho más legibles que el código de máquina. Dependiendo de la arquitectura, estos elementos también pueden combinarse para instrucciones específicas o modos de direccionamiento.utilizando compensaciones u otros datos, así como direcciones fijas. Muchos ensambladores ofrecen mecanismos adicionales para facilitar el desarrollo de programas, controlar el proceso de ensamblaje y ayudar a la depuración .

Terminología

  • Un ensamblador de macros incluye una función de macroinstrucción para que el texto en lenguaje ensamblador (parametrizado) se pueda representar con un nombre, y ese nombre se puede usar para insertar el texto expandido en otro código.
  • Un ensamblador cruzado (ver también compilador cruzado ) es un ensamblador que se ejecuta en una computadora o sistema operativo (el sistema host ) de un tipo diferente del sistema en el que se ejecutará el código resultante (el sistema de destino ). El ensamblaje cruzado facilita el desarrollo de programas para sistemas que no tienen los recursos para soportar el desarrollo de software, como un sistema integrado o un microcontrolador . En tal caso, el código de objeto resultante debe transferirse al sistema de destino, a través de una memoria de solo lectura (ROM, EPROM , etc.), un programador(cuando la memoria de solo lectura está integrada en el dispositivo, como en los microcontroladores), o un enlace de datos utilizando una copia exacta bit a bit del código objeto o una representación basada en texto de ese código (como Intel hex o Motorola S-record ).
  • Un ensamblador de alto nivel es un programa que proporciona abstracciones de lenguaje asociadas más a menudo con lenguajes de alto nivel, como estructuras de control avanzadas ( IF / THEN / ELSE , DO CASE, etc.) y tipos de datos abstractos de alto nivel, incluidas estructuras / registros, uniones, clases y conjuntos.
  • Un microensamblador es un programa que ayuda a preparar un microprograma , llamado firmware , para controlar el funcionamiento de bajo nivel de una computadora.
  • Un meta-ensamblador es "un programa que acepta la descripción sintáctica y semántica de un lenguaje ensamblador y genera un ensamblador para ese lenguaje". [10] Los ensambladores de "meta-símbolo" para las series de computadoras SDS 9 y SDS Sigma son metaensambladores. [11] [nb 1] Sperry Univac también proporcionó un metaensamblador para la serie UNIVAC 1100/2200 . [12]
  • El ensamblador en línea (o ensamblador incrustado ) es un código ensamblador contenido dentro de un programa de lenguaje de alto nivel. [13] Esto se usa con mayor frecuencia en programas de sistemas que necesitan acceso directo al hardware.

Conceptos clave

Ensamblador

Un ensamblador programa crea código objeto por traducir combinaciones de mnemotécnicos y la sintaxis para las operaciones y modos de direccionamiento en sus equivalentes numéricos. Esta representación incluye típicamente un código de operación (" código de operación ") así como otros bits de control y datos. El ensamblador también calcula expresiones constantes y resuelve nombres simbólicos para ubicaciones de memoria y otras entidades. [14] El uso de referencias simbólicas es una característica clave de los ensambladores, ya que ahorra tediosos cálculos y actualizaciones manuales de direcciones después de las modificaciones del programa. La mayoría de los ensambladores también incluyenmacro facilidades para realizar sustitución textual - por ejemplo, para generar secuencias cortas comunes de instrucciones como en línea , en lugar de llamadas subrutinas .

Algunos ensambladores también pueden realizar algunos tipos simples de optimizaciones específicas del conjunto de instrucciones . Un ejemplo concreto de esto pueden ser los omnipresentes ensambladores x86 de varios proveedores. Llamado tamaño de salto , [14] la mayoría de ellos son capaces de realizar reemplazos de instrucciones de salto (saltos largos reemplazados por saltos cortos o relativos) en cualquier número de pases, a pedido. Otros pueden incluso hacer una simple reorganización o inserción de instrucciones, como algunos ensambladores para arquitecturas RISC que pueden ayudar a optimizar una programación de instrucciones sensata para explotar la canalización de la CPU de la manera más eficiente posible. [ cita requerida ]

Los ensambladores han estado disponibles desde la década de 1950, como primer paso por encima del lenguaje máquina y antes de los lenguajes de programación de alto nivel como Fortran , Algol , COBOL y Lisp . También ha habido varias clases de traductores y generadores de código semiautomáticos con propiedades similares a los lenguajes ensambladores y de alto nivel, con Speedcode como quizás uno de los ejemplos más conocidos.

Puede haber varios ensambladores con diferente sintaxis para una CPU particular o una arquitectura de conjunto de instrucciones . Por ejemplo, una instrucción para agregar datos de memoria a un registro en un procesador de la familia x86 podría estar add eax,[ebx], en la sintaxis original de Intel , mientras que esto estaría escrito addl (%ebx),%eaxen la sintaxis de AT&T utilizada por GNU Assembler . A pesar de las diferentes apariencias, las diferentes formas sintácticas generalmente generan el mismo código de máquina numérico . Un solo ensamblador también puede tener diferentes modos para admitir variaciones en las formas sintácticas, así como sus interpretaciones semánticas exactas (como FASM -sintaxis,TASM -sintaxis, modo ideal, etc., en el caso especial de la programación de ensamblajes x86 ).

Número de pases

Hay dos tipos de ensambladores basados ​​en cuántos pases a través de la fuente se necesitan (cuántas veces el ensamblador lee la fuente) para producir el archivo de objeto.

  • Los ensambladores de una pasada revisan el código fuente una vez. Cualquier símbolo usado antes de ser definido requerirá una "errata" al final del código de objeto (o, al menos, no antes del punto donde se define el símbolo) que le indique al vinculador o al cargador que "retroceda" y sobrescriba un marcador de posición que se había dejado donde se usó el símbolo aún no definido.
  • Los ensambladores de múltiples pasadas crean una tabla con todos los símbolos y sus valores en las primeras pasadas, luego usan la tabla en pasadas posteriores para generar código.

En ambos casos, el ensamblador debe poder determinar el tamaño de cada instrucción en las pasadas iniciales para calcular las direcciones de los símbolos subsiguientes. Esto significa que si el tamaño de una operación que se refiere a un operando definido más adelante depende del tipo o la distancia del operando, el ensamblador hará una estimación pesimista cuando encuentre la operación por primera vez y, si es necesario, la rellenará con uno o más " no -operación "instrucciones en una pasada posterior o la errata. En un ensamblador con optimización de mirilla , las direcciones pueden recalcularse entre pasadas para permitir reemplazar el código pesimista con código adaptado a la distancia exacta del objetivo.

La razón original para el uso de ensambladores de un solo paso fue el tamaño de la memoria y la velocidad de ensamblaje; a menudo, un segundo paso requeriría almacenar la tabla de símbolos en la memoria (para manejar referencias hacia adelante ), rebobinar y releer la fuente del programa en cinta o releer un baraja de cartas o cinta de papel perforada . Las computadoras posteriores con memorias mucho más grandes (especialmente almacenamiento en disco), tenían el espacio para realizar todo el procesamiento necesario sin tal relectura. La ventaja del ensamblador de múltiples pasadas es que la ausencia de erratas hace que el proceso de vinculación (o la carga del programa si el ensamblador produce directamente código ejecutable) sea más rápido. [15]

Ejemplo: en el siguiente fragmento de código, un ensamblador de un solo paso podría determinar la dirección de la referencia hacia atrás BKWD al ensamblar la instrucción S2 , pero no podría determinar la dirección de la referencia directa FWD al ensamblar la instrucción de rama S1 ; de hecho, FWD puede no estar definido. Un ensamblador de dos pasos determinaría ambas direcciones en el paso 1, por lo que serían conocidas al generar el código en el paso 2.

S1 B FWD ...FWD EQU * ...BKWD EQU * ...S2 B BKWD

Ensambladores de alto nivel

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

  • Declaraciones e invocaciones de procedimientos / funciones de alto nivel
  • Estructuras de control avanzadas (IF / THEN / ELSE, SWITCH)
  • Tipos de datos abstractos de alto nivel, incluidas estructuras / registros, uniones, clases y conjuntos
  • Procesamiento de macros sofisticado (aunque disponible en ensambladores ordinarios desde finales de la década de 1950 para, por ejemplo, la serie IBM 700 y la serie IBM 7000 , y desde la década de 1960 para IBM System / 360 (S / 360), entre otras máquinas)
  • Funciones de programación orientadas a objetos como clases , objetos , abstracción , polimorfismo y herencia [16]

Consulte Diseño de idiomas a continuación para obtener más detalles.

Lenguaje ensamblador

Un programa escrito en lenguaje ensamblador consta de una serie de instrucciones de procesador mnemotécnicas y meta-declaraciones (conocidas como directivas, pseudo-instrucciones y pseudo-operaciones), comentarios y datos. Las instrucciones en lenguaje ensamblador generalmente consisten en un mnemónico de código de operación seguido de un operando , que puede ser una lista de datos, argumentos o parámetros. [17] Algunas instrucciones pueden estar "implícitas", lo que significa que los datos sobre los que opera la instrucción están implícitamente definidos por la instrucción misma; dicha instrucción no toma un operando. La declaración resultante es traducida por un ensamblador a instrucciones en lenguaje de máquina que pueden cargarse en la memoria y ejecutarse.

Por ejemplo, la siguiente instrucción le dice a un procesador x86 / IA-32 que mueva un valor inmediato de 8 bits a un registro . El código binario para esta instrucción es 10110 seguido de un identificador de 3 bits para qué registro usar. El identificador para el registro AL es 000, por lo que el siguiente código de máquina carga el registro AL con los datos 01100001. [17]

10110000 01100001

Este código informático binario se puede hacer más legible por humanos expresándolo en hexadecimal de la siguiente manera.

B0 61

Aquí, B0significa 'Mover una copia del siguiente valor a AL , y 61es una representación hexadecimal del valor 01100001, que es 97 en decimal . El lenguaje ensamblador para la familia 8086 proporciona el mnemónico MOV (una abreviatura de mover ) para instrucciones como esta, por lo que el código de máquina anterior se puede escribir de la siguiente manera en lenguaje ensamblador, completo con un comentario explicativo si es necesario, después del punto y coma. Esto es mucho más fácil de leer y recordar.

MOV  AL ,  61 h  ; Cargue AL con 97 decimal (61 hexadecimal)

En algunos lenguajes ensambladores (incluido este), el mismo mnemónico, como MOV, puede usarse para una familia de instrucciones relacionadas para cargar, copiar y mover datos, ya sean valores inmediatos, valores en registros o ubicaciones de memoria señaladas por valores en registros o por direcciones inmediatas (también conocidas como directas). Otros ensambladores pueden usar nemotécnicos de código de operación separados, como L para "mover memoria a registro", ST para "mover registro a memoria", LR para "mover registro a registro", MVI para "mover operando inmediato a memoria", etc.

Si se usa el mismo mnemónico para diferentes instrucciones, eso significa que el mnemónico corresponde a varios códigos de instrucción binaria diferentes, excluyendo datos (por ejemplo, 61hen este ejemplo), dependiendo de los operandos que siguen al mnemónico. Por ejemplo, para las CPU x86 / IA-32, la sintaxis del lenguaje ensamblador de Intel MOV AL, AHrepresenta una instrucción que mueve el contenido del registro AH al registro AL . La forma hexadecimal [nb 2] de esta instrucción es:

88 E0

El primer byte, 88h, identifica un movimiento entre un registro del tamaño de un byte y otro registro o memoria, y el segundo byte, E0h, se codifica (con tres campos de bits) para especificar que ambos operandos son registros, la fuente es AH y el destino es AL .

En un caso como este, donde el mismo mnemónico puede representar más de una instrucción binaria, el ensamblador determina qué instrucción generar examinando los operandos. En el primer ejemplo, el operando 61hes una constante numérica hexadecimal válida y no es un nombre de registro válido, por lo que solo la B0instrucción puede ser aplicable. En el segundo ejemplo, el operando AHes un nombre de registro válido y no una constante numérica válida (hexadecimal, decimal, octal o binario), por lo que solo la 88instrucción puede ser aplicable.

Los lenguajes ensambladores siempre están diseñados para que este tipo de falta de ambigüedad sea universalmente reforzado por su sintaxis. Por ejemplo, en el lenguaje ensamblador Intel x86, una constante hexadecimal debe comenzar con un dígito numérico, de modo que el número hexadecimal 'A' (igual al diez decimal) se escriba como 0Aho 0AHno AH, específicamente para que no parezca ser el nombre del registro AH . (La misma regla también evita la ambigüedad con los nombres de los registros BH , CH y DH , así como con cualquier símbolo definido por el usuario que termine con la letra H y que, de lo contrario, contenga solo caracteres que sean dígitos hexadecimales, como la palabra "PLAYA ".)

Volviendo al ejemplo original, mientras que el código de operación x86 10110000 ( B0) copia un valor de 8 bits en el registro AL , 10110001 ( B1) lo mueve a CL y 10110010 ( B2) lo hace a DL . A continuación se muestran ejemplos en lenguaje ensamblador para estos. [17]

MOV  AL ,  1h  ; Cargar AL con valor inmediato 1 MOV  CL ,  2h  ; Cargar CL con valor inmediato 2 MOV  DL ,  3h  ; Cargar DL con valor inmediato 3

La sintaxis de MOV también puede ser más compleja, como muestran los siguientes ejemplos. [18]

MOV  EAX ,  [ EBX ]  ; Mueva los 4 bytes en la memoria en la dirección contenida en EBX en EAX MOV  [ ESI + EAX ],  CL  ; Mueva el contenido de CL al byte en la dirección ESI + EAX MOV  DS ,  DX  ; Mueva el contenido de DX al registro de segmento DS

En cada caso, el mnemónico MOV se traduce directamente a uno de los códigos de operación 88-8C, 8E, A0-A3, B0-BF, C6 o C7 por un ensamblador, y el programador normalmente no tiene que saber ni recordar cuál. [17]

Transformar el lenguaje ensamblador en código de máquina es el trabajo de un ensamblador, y lo contrario puede lograrse, al menos parcialmente, mediante un desensamblador . A diferencia de los lenguajes de alto nivel , existe una correspondencia uno a uno entre muchas instrucciones de ensamblaje simples e instrucciones en lenguaje de máquina. Sin embargo, en algunos casos, un ensamblador puede proporcionar pseudoinstrucciones(esencialmente macros) que se expanden en varias instrucciones en lenguaje de máquina para proporcionar la funcionalidad comúnmente necesaria. Por ejemplo, para una máquina que carece de una instrucción "bifurcar si es mayor o igual", un ensamblador puede proporcionar una pseudoinstrucción que se expanda a la máquina "establecer si es menor que" y "bifurcar si es cero (en el resultado de la instrucción establecida)". . La mayoría de los ensambladores con todas las funciones también proporcionan una rica macrolenguaje (discutido a continuación) que es utilizado por proveedores y programadores para generar secuencias de datos y código más complejas. Dado que la información sobre pseudoinstrucciones y macros definidas en el entorno del ensamblador no está presente en el programa objeto, un desensamblador no puede reconstruir las invocaciones de macros y pseudoinstrucciones, sino que solo puede desensamblar las instrucciones de máquina reales que el ensamblador generó a partir de esas entidades abstractas del lenguaje ensamblador. Del mismo modo, dado que el ensamblador ignora los comentarios en el archivo fuente del lenguaje ensamblador y no tienen ningún efecto en el código objeto que genera, un desensamblador siempre es completamente incapaz de recuperar los comentarios fuente.

Cada arquitectura de computadora tiene su propio lenguaje de máquina. Las computadoras difieren en el número y tipo de operaciones que admiten, en los diferentes tamaños y números de registros y en las representaciones de los datos almacenados. Si bien la mayoría de las computadoras de uso general pueden realizar esencialmente la misma funcionalidad, las formas en que lo hacen difieren; los lenguajes ensambladores correspondientes reflejan estas diferencias.

Pueden existir múltiples conjuntos de mnemónicos o sintaxis en lenguaje ensamblador para un solo conjunto de instrucciones, típicamente instanciadas en diferentes programas ensambladores. En estos casos, el más popular suele ser el suministrado por el fabricante de la CPU y utilizado en su documentación.

Dos ejemplos de CPU que tienen dos conjuntos diferentes de nemotécnicos son la familia Intel 8080 y la Intel 8086/8088. Debido a que Intel reclamó los derechos de autor sobre sus nemotécnicos en lenguaje ensamblador (en cada página de su documentación publicada en la década de 1970 y principios de los 80, al menos), algunas empresas que producían de forma independiente CPU compatibles con los conjuntos de instrucciones de Intel inventaron sus propios nemotécnicos. La CPU Zilog Z80 , una mejora del Intel 8080A , admite todas las instrucciones del 8080A y muchas más; Zilog inventó un lenguaje ensamblador completamente nuevo, no solo para las nuevas instrucciones sino también para todas las instrucciones del 8080A. Por ejemplo, cuando Intel usa los mnemónicos MOV , MVI , LDA , STA ,LXI , LDAX , STAX , LHLD y SHLD para varias instrucciones de transferencia de datos, el lenguaje ensamblador Z80 usa el mnemónico LD para todas ellas. Un caso similar es el de las CPU NEC V20 y V30 , copias mejoradas de Intel 8086 y 8088, respectivamente. Al igual que Zilog con el Z80, NEC inventó nuevos mnemónicos para todas las instrucciones 8086 y 8088, para evitar acusaciones de infracción de los derechos de autor de Intel. (Es cuestionable si tales derechos de autor pueden ser válidos, y las empresas de CPU posteriores, como AMD [nb 3] y Cyrixvolvió a publicar los mnemónicos de instrucción x86 / IA-32 de Intel exactamente sin permiso ni sanción legal.) Es dudoso que en la práctica muchas personas que programaron el V20 y el V30 escribieran en el lenguaje ensamblador de NEC en lugar del lenguaje de Intel; Dado que dos lenguajes ensambladores cualesquiera para la misma arquitectura de conjunto de instrucciones son isomórficos (algo así como el inglés y el latín de cerdo ), no es necesario utilizar el lenguaje ensamblador publicado por el propio fabricante con los productos de ese fabricante.

Diseño de lenguaje

Elementos básicos

Existe un gran grado de diversidad en la forma en que los autores de ensambladores categorizan las declaraciones y en la nomenclatura que utilizan. En particular, algunos describen cualquier cosa que no sea un mnemónico de máquina o un mnemónico extendido como una pseudooperación (pseudo-op). Un lenguaje ensamblador típico consta de 3 tipos de instrucciones que se utilizan para definir las operaciones del programa:

  • Mnemónicos de código de operación
  • Definiciones de datos
  • Directivas de montaje

Mnemónicos de código de operación y mnemónicos extendidos

Las instrucciones (declaraciones) en lenguaje ensamblador son generalmente muy simples, a diferencia de las de los lenguajes de alto nivel . Generalmente, un mnemónico es un nombre simbólico para una sola instrucción ejecutable en lenguaje de máquina (un código de operación ), y hay al menos un mnemónico de código de operación definido para cada instrucción en lenguaje de máquina. Cada instrucción generalmente consta de una operación o código de operación más cero o más operandos. La mayoría de las instrucciones se refieren a un solo valor o un par de valores. Los operandos pueden ser inmediatos (valor codificado en la propia instrucción), registros especificados en la instrucción o implícitos, o las direcciones de los datos ubicados en otro lugar del almacenamiento. Esto está determinado por la arquitectura del procesador subyacente: el ensamblador simplemente refleja cómo funciona esta arquitectura. Los mnemónicos extendidos se utilizan a menudo para especificar una combinación de un código de operación con un operando específico, por ejemplo, los ensambladores System / 360 usan Bcomo un mnemónico extendido para BCcon una máscara de 15 y NOP("NO OPeration" - no hacer nada para un paso) para BCcon una máscara de 0.

Los mnemónicos extendidos se utilizan a menudo para respaldar usos especializados de instrucciones, a menudo con fines que no son obvios a partir del nombre de la instrucción. Por ejemplo, muchas CPU no tienen una instrucción NOP explícita, pero tienen instrucciones que se pueden usar para ese propósito. En las CPU 8086 se utiliza la instrucción , siendo un pseudo-código de operación para codificar la instrucción . Algunos desensambladores reconocen esto y decodificarán la instrucción como . De manera similar, los ensambladores de IBM para System / 360 y System / 370 usan los mnemónicos extendidos y para y con máscaras cero. Para la arquitectura SPARC, se conocen como instrucciones sintéticas .xchg ax,axnopnopxchg ax,axxchg ax,axnopNOPNOPRBCBCR[19]

Algunos ensambladores también admiten macroinstrucciones integradas simples que generan dos o más instrucciones de máquina. Por ejemplo, con algunos ensambladores Z80, ld hl,bcse reconoce que la instrucción genera ld l,cseguido de ld h,b. [20] Estos a veces se conocen como pseudo-opcodes .

Los mnemónicos son símbolos arbitrarios; en 1985 el IEEE publicó el Estándar 694 para un conjunto uniforme de mnemónicos para ser utilizado por todos los ensambladores. Desde entonces, la norma ha sido retirada.

Directivas de datos

Hay instrucciones que se utilizan para definir elementos de datos para contener datos y variables. Definen el tipo de datos, la longitud y la alineación de los datos. Estas instrucciones también pueden definir si los datos están disponibles para programas externos (programas ensamblados por separado) o solo para el programa en el que se define la sección de datos. Algunos ensambladores los clasifican como pseudo-operaciones.

Directivas de montaje

Las directivas de ensamblaje, también llamadas pseudo-opcodes, pseudo-operaciones o pseudo-operaciones, son comandos que se le dan a un ensamblador "dirigiéndolo a realizar operaciones distintas a las instrucciones de ensamblaje". [14] Las directivas afectan la forma en que opera el ensamblador y "pueden afectar el código objeto, la tabla de símbolos, el archivo de listado y los valores de los parámetros internos del ensamblador". A veces, el término pseudo-opcode se reserva para las directivas que generan código objeto, como las que generan datos. [21]

Los nombres de las pseudo-operaciones a menudo comienzan con un punto para distinguirlos de las instrucciones de la máquina. Las pseudo-operaciones pueden hacer que el ensamblaje del programa dependa de los parámetros ingresados ​​por un programador, de modo que un programa se puede ensamblar de diferentes maneras, quizás para diferentes aplicaciones. O se puede utilizar una pseudo-operación para manipular la presentación de un programa para que sea más fácil de leer y mantener. Otro uso común de las pseudo-operaciones es reservar áreas de almacenamiento para datos en tiempo de ejecución y, opcionalmente, inicializar su contenido a valores conocidos.

Los ensambladores simbólicos permiten a los programadores asociar nombres arbitrarios ( etiquetas o símbolos ) con ubicaciones de memoria y varias constantes. Por lo general, a cada constante y variable se le asigna un nombre para que las instrucciones puedan hacer referencia a esas ubicaciones por su nombre, promoviendo así el código autodocumentado . En el código ejecutable, el nombre de cada subrutina está asociado con su punto de entrada, por lo que cualquier llamada a una subrutina puede usar su nombre. Dentro de las subrutinas, los destinos GOTO reciben etiquetas. Algunos ensambladores admiten símbolos locales que a menudo son léxicamente distintos de los símbolos normales (por ejemplo, el uso de "10 $" como destino GOTO).

Algunos ensambladores, como NASM , brindan administración de símbolos flexible, lo que permite a los programadores administrar diferentes espacios de nombres , calcular automáticamente las compensaciones dentro de las estructuras de datos y asignar etiquetas que se refieren a valores literales o al resultado de cálculos simples realizados por el ensamblador. Las etiquetas también se pueden utilizar para inicializar constantes y variables con direcciones reubicables.

Los lenguajes ensambladores, como la mayoría de los otros lenguajes informáticos, permiten que se agreguen comentarios al código fuente del programa que se ignorarán durante el ensamblaje. Los comentarios juiciosos son esenciales en los programas de lenguaje ensamblador, ya que el significado y el propósito de una secuencia de instrucciones de máquina binaria pueden ser difíciles de determinar. El lenguaje ensamblador "crudo" (sin comentarios) generado por compiladores o desensambladores es bastante difícil de leer cuando se deben realizar cambios.

Macros

Muchos ensambladores admiten macros predefinidas y otros admiten macros definidas por el programador (y redefinidas repetidamente) que involucran secuencias de líneas de texto en las que se incrustan variables y constantes. La definición de macro es más comúnmente [nb 4]una mezcla de declaraciones de ensamblador, por ejemplo, directivas, instrucciones de máquina simbólicas y plantillas para declaraciones de ensamblador. Esta secuencia de líneas de texto puede incluir códigos de operación o directivas. Una vez que se ha definido una macro, su nombre puede usarse en lugar de un mnemónico. Cuando el ensamblador procesa tal declaración, reemplaza la declaración con las líneas de texto asociadas con esa macro, luego las procesa como si existieran en el archivo de código fuente (incluida, en algunos ensambladores, la expansión de cualquier macros existente en el texto de reemplazo) . En este sentido, las macros datan de los autocodificadores de IBM de la década de 1950. [22] [nb 5]

En lenguaje ensamblador, el término "macro" representa un concepto más completo que en otros contextos, como el preprocesador en el lenguaje de programación C , donde su directiva #define se usa típicamente para crear macros cortas de una sola línea. Las macroinstrucciones del ensamblador, como las macros en PL / I y algunos otros lenguajes, pueden ser "programas" extensos por sí mismos, ejecutados por interpretación del ensamblador durante el ensamblaje.

Dado que las macros pueden tener nombres 'cortos' pero expandirse a varias o 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 ocurre con los lenguajes de nivel superior. También se pueden usar para agregar niveles más altos de estructura a los programas de ensamblaje, opcionalmente introducir código de depuración incrustado a través de parámetros y otras características similares.

Los ensambladores de macros a menudo permiten que las macros tomen parámetros . Algunos ensambladores incluyen lenguajes de macros bastante sofisticados, incorporando elementos de lenguaje de alto nivel como parámetros opcionales, variables simbólicas, condicionales, manipulación de cadenas y operaciones aritméticas, todos utilizables durante la ejecución de una macro determinada y que permiten que las macros guarden contexto o intercambien información. . Por tanto, una macro puede generar numerosas instrucciones en lenguaje ensamblador o definiciones de datos, basadas en los argumentos de la macro. Esto podría usarse para generar estructuras de datos de estilo de registro o " desenrollado"bucles, por ejemplo, o podría generar algoritmos completos basados ​​en parámetros complejos. Por ejemplo, una macro" sort "podría aceptar la especificación de una clave de ordenación compleja y generar código diseñado para esa clave específica, sin necesidad de las pruebas en tiempo de ejecución que Se necesitaría para un procedimiento general que interpreta la especificación. Se puede considerar que una organización que usa lenguaje ensamblador que se ha extendido mucho usando un conjunto de macros de este tipo está trabajando en un lenguaje de nivel superior, ya que dichos programadores no están trabajando con el nivel más bajo de una computadora. elementos conceptuales. Subrayando este punto, se utilizaron macros para implementar una máquina virtual temprana en SNOBOL4(1967), que fue escrito en SNOBOL Implementation Language (SIL), un lenguaje ensamblador para una máquina virtual. La máquina de destino traduciría esto a su código nativo usando un ensamblador de macros . [23] Esto permitió un alto grado de portabilidad para el momento.

Las macros se utilizaron para personalizar sistemas de software a gran escala para clientes específicos en la era del mainframe y también fueron utilizadas por el personal del cliente para satisfacer las necesidades de sus empleadores mediante la creación de versiones específicas de los sistemas operativos de los fabricantes. Esto lo hicieron, por ejemplo, programadores de sistemas que trabajaban con el sistema de monitorización conversacional / máquina virtual ( VM / CMS ) de IBM y con los complementos de "procesamiento de transacciones en tiempo real" de IBM, el sistema de control de información del cliente CICS y ACP / TPF . la aerolínea / sistema financiero que comenzó en la década de 1970 y que todavía opera muchos grandes sistemas de reserva por computadora (CRS) y sistemas de tarjetas de crédito en la actualidad.

También es posible utilizar únicamente las capacidades 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 ensamblador de macros puro que contiene líneas de código COBOL dentro de los operadores de tiempo de ensamblaje. instruir al ensamblador para que genere código arbitrario. IBM OS / 360 utiliza macros para realizar la generación del sistema . El usuario especifica opciones codificando una serie de macros de ensamblador. El ensamblaje de estas macros genera una secuencia de trabajos para construir el sistema, incluido el lenguaje de control de trabajos y las declaraciones de control de utilidades .

Esto se debe a que, como se advirtió en la década de 1960, el concepto de "macroprocesamiento" es independiente del concepto de "ensamblaje", siendo el primero en términos modernos más procesamiento de texto, procesamiento de texto, que generación de código objeto. El concepto de procesamiento de macros apareció y aparece en el lenguaje de programación C, que admite "instrucciones de preprocesador" para establecer variables y realizar pruebas condicionales sobre sus valores. A diferencia de ciertos procesadores de macros anteriores dentro de ensambladores, el preprocesador de C no es Turing completo porque carece de la capacidad de realizar un ciclo o "ir a", lo que permite que los programas lo hagan.

A pesar del poder del procesamiento de macros, cayó en desuso en muchos lenguajes de alto nivel (las principales excepciones son C , C ++ y PL / I) sin dejar de ser una constante para los ensambladores.

La sustitución de parámetros de macros se realiza estrictamente por nombre: en el momento del procesamiento de macros, el valor de un parámetro se sustituye textualmente por su nombre. La clase de errores más famosa resultante fue el uso de un parámetro que en sí mismo era una expresión y no un nombre simple cuando el escritor de macros esperaba un nombre. En la macro:

foo: macro a
cargar a * b

la intención era que la persona que llama proporcionara el nombre de una variable, y la variable "global" o la constante b se utilizaría para multiplicar "a". Si se llama a foo con el parámetro a-c, se load a-c*bproduce la expansión macro de . Para evitar cualquier posible ambigüedad, los usuarios de procesadores de macros pueden poner entre paréntesis los parámetros formales dentro de las definiciones de macros, o los llamadores pueden poner entre paréntesis los parámetros de entrada. [24]

Soporte para programación estructurada

Se han escrito paquetes de macros que proporcionan elementos de programación estructurados para codificar el flujo de ejecución. El primer ejemplo de este enfoque estaba en el conjunto de macros Concept-14 , [25] propuesto originalmente por Harlan Mills (marzo de 1970), e implementado por Marvin Kessler en la División de Sistemas Federales de IBM, que proporcionó IF / ELSE / ENDIF y un flujo de control similar. bloques para programas ensambladores OS / 360. Esta fue una forma de reducir o eliminar el uso de operaciones GOTO en código ensamblador, uno de los principales factores que causan el código espagueti en lenguaje ensamblador. Este enfoque fue ampliamente aceptado a principios de la década de 1980 (los últimos días del uso del lenguaje ensamblador a gran escala). Kit de herramientas de ensamblador de alto nivel de IBM[26] incluye un paquete de macros de este tipo.

Un diseño curioso fue A-natural , un ensamblador "orientado a flujo" para 8080 / Z80 , procesadores [ cita requerida ] de Whitesmiths Ltd. (desarrolladores del sistema operativo Idris similar a Unix , y lo que se informó que fue el primer C comercial compilador ). El lenguaje se clasificó como ensamblador porque trabajaba con elementos de máquina en bruto, como códigos de operación , registrosy referencias de memoria; pero incorporó 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 estructuradas orientadas a bloques, controlaban la secuencia de las instrucciones generadas. A-natural se construyó como el lenguaje de objetos de un compilador de C, en lugar de para la codificación manual, pero su sintaxis lógica ganó algunos fanáticos.

Ha habido poca demanda aparente de ensambladores más sofisticados desde el declive del desarrollo del lenguaje ensamblador a gran escala. [27] A pesar de eso, todavía se están desarrollando y aplicando en los casos en que las limitaciones de recursos o las peculiaridades en la arquitectura del sistema de destino impiden el uso eficaz de lenguajes de nivel superior. [28]

Los ensambladores con un potente motor de macros permiten la programación estructurada a través de macros, como la macro de conmutador proporcionada con el paquete Masm32 (este código es un programa completo):

include  \ masm32 \ include \ masm32rt.inc ; usar la biblioteca Masm32.code demomain:  REPEAT  20 switch  rv ( nrandom ,  9 ) ; genera un número entre 0 y 8 mov  ecx ,  7 case  0 imprime  "case 0" case  ecx ; a diferencia de la mayoría de los otros lenguajes de programación, imprima  "case 7" ; el modificador Masm32 permite "casos variables" caso  1  ..  3 .if  eax == 1 imprime  "caso 1" .elseif  eax == 2 imprime  "caso 2" .else imprime "casos 1 a 3: otros" .endif caso  4 ,  6 ,  8 imprimir  "casos 4, 6 u 8" por defecto mov  ebx ,  19  ; imprimir 20 estrellas. Repita la impresión  "*" dec  ebx. ¿ Hasta el  Si gn?  ; bucle hasta que se establezca el indicador de señal finaliza w print  ch r $ ( 13 ,  10 )  ENDM  exit end  demomain

Uso de lenguaje ensamblador

Perspectiva histórica

Los lenguajes ensambladores no estaban disponibles en el momento en que se introdujo la computadora de programa almacenado . Kathleen Booth "tiene el mérito de haber inventado el lenguaje ensamblador" [29] [30] basado en el trabajo teórico que comenzó en 1947, mientras trabajaba en el ARC2 en Birkbeck, Universidad de Londres tras la consulta de Andrew Booth (más tarde su esposo) con el matemático John von Neumann y el físico Herman Goldstine del Instituto de Estudios Avanzados . [30] [31]

A finales de 1948, la Calculadora Automática de Almacenamiento con Retraso Electrónico (EDSAC) tenía un ensamblador (llamado "pedidos iniciales") integrado en su programa de arranque . Utilizaba mnemotécnicos de una letra desarrollados por David Wheeler , a quien la IEEE Computer Society acredita como el creador del primer "ensamblador". [14] [32] [33] Los informes sobre el EDSAC introdujeron el término "ensamblaje" para el proceso de combinar campos en una palabra de instrucción. [34] SOAP ( Programa de ensamblaje óptimo simbólico ) era un lenguaje ensamblador para la computadora IBM 650 escrito por Stan Poley en 1955. [35]

Los lenguajes ensambladores eliminan gran parte de la programación de primera generación , propensa a errores, tediosa y que consume mucho tiempo, necesaria en las primeras computadoras, liberando a los programadores del tedio, como recordar códigos numéricos y calcular direcciones.

Los lenguajes ensambladores alguna vez fueron ampliamente utilizados para todo tipo de programación. Sin embargo, en la década de 1980 (década de 1990 en microcomputadoras ), su uso había sido reemplazado en gran medida por lenguajes de nivel superior, en la búsqueda de una mejora en la productividad de la programación . Hoy en día, el lenguaje ensamblador todavía se usa para la manipulación directa de hardware, el acceso a instrucciones de procesador especializadas o para abordar problemas críticos de rendimiento. Los usos típicos son controladores de dispositivos , sistemas integrados de bajo nivel y sistemas en tiempo real.

Históricamente, numerosos programas se han escrito íntegramente en lenguaje ensamblador. El Burroughs MCP (1961) fue el primer ordenador para el que no se desarrolló un sistema operativo enteramente en lenguaje ensamblador; fue escrito en Lenguaje Orientado a Problemas de Sistemas Ejecutivos (ESPOL), un dialecto de Algol. Muchas aplicaciones comerciales también se escribieron en lenguaje ensamblador, incluida una gran cantidad de software de mainframe de IBM escrito por grandes corporaciones. COBOL , FORTRAN y algunos PL / I eventualmente desplazaron gran parte de este trabajo, aunque varias organizaciones grandes conservaron las infraestructuras de aplicaciones en lenguaje ensamblador hasta bien entrada la década de 1990.

La mayoría de las primeras microcomputadoras se basaron en el lenguaje ensamblador codificado a mano, incluida la mayoría de los sistemas operativos y aplicaciones grandes. Esto se debía a que estos sistemas tenían graves limitaciones de recursos, imponían arquitecturas de visualización y memoria idiosincrásicas y proporcionaban servicios de sistema limitados y con errores. Quizás más importante fue la falta de compiladores de lenguaje de alto nivel de primera clase adecuados para el uso de microcomputadoras. Un factor psicológico también puede haber jugado un papel: la primera generación de programadores de microcomputadoras mantuvo una actitud de aficionado, "alambres y alicates".

En un contexto más comercial, las razones más importantes para usar el lenguaje ensamblador fueron una hinchazón mínima (tamaño), una sobrecarga mínima, una mayor velocidad y confiabilidad.

Ejemplos típicos de grandes programas en lenguaje ensamblador de esta época son los sistemas operativos IBM PC DOS , el compilador Turbo Pascal y aplicaciones tempranas como el programa de hoja de cálculo Lotus 1-2-3 . El lenguaje ensamblador se usó para obtener el mejor rendimiento de Sega Saturn , una consola que fue notoriamente desafiante para desarrollar y programar juegos. [36] El juego de arcade de 1993 NBA Jam es otro ejemplo.

El lenguaje ensamblador ha sido durante mucho tiempo el lenguaje de desarrollo principal para muchas computadoras domésticas populares de las décadas de 1980 y 1990 (como MSX , Sinclair ZX Spectrum , Commodore 64 , Commodore Amiga y Atari ST ). Esto se debió en gran parte a que los dialectos BÁSICOS interpretados en estos sistemas ofrecían una velocidad de ejecución insuficiente, así como instalaciones insuficientes para aprovechar al máximo el hardware disponible en estos sistemas. Algunos sistemas incluso tienen un entorno de desarrollo integrado (IDE) con funciones de macro y depuración muy avanzadas. Algunos compiladores disponibles para Radio Shack TRS-80y sus sucesores tenían la capacidad de combinar la fuente de ensamblado en línea con declaraciones de programa de alto nivel. Tras la compilación, un ensamblador incorporado produjo un código de máquina en línea.

Uso actual

Siempre ha habido [37] debates sobre la utilidad y el rendimiento del lenguaje ensamblador en relación con los lenguajes de alto nivel.

Aunque el lenguaje ensamblador tiene usos de nicho específicos donde es importante (ver más abajo), existen otras herramientas para la optimización. [38]

En julio de 2017 , el índice TIOBE de popularidad del lenguaje de programación clasifica al lenguaje ensamblador en el puesto 11, por delante de Visual Basic , por ejemplo. [39] El ensamblador se puede utilizar para optimizar la velocidad u optimizar el tamaño. En el caso de la optimización de la velocidad, se afirma [40] que los compiladores de optimización modernos convierten los lenguajes de alto nivel en código que puede ejecutarse tan rápido como un ensamblaje escrito a mano, a pesar de los contraejemplos que se pueden encontrar. [41] [42] [43] La complejidad de los procesadores y subsistemas de memoria modernos hace que la optimización eficaz sea cada vez más difícil para los compiladores, así como para los programadores de ensambladores. [44] [45]Además, el aumento del rendimiento del procesador ha significado que la mayoría de las CPU permanezcan inactivas la mayor parte del tiempo, [46] con retrasos causados ​​por cuellos de botella predecibles como fallas de caché, operaciones de E / S y paginación . Esto ha hecho que la velocidad de ejecución del código sin formato no sea un problema para muchos programadores.

Hay algunas situaciones en las que los desarrolladores pueden optar por utilizar el lenguaje ensamblador:

  • Escribir código para sistemas con procesadores más antiguos [ aclaración necesaria ] que tienen opciones limitadas de lenguaje de alto nivel como Atari 2600 , Commodore 64 y calculadoras gráficas . [47] Los programas para estas computadoras de las décadas de 1970 y 1980 a menudo se escriben en el contexto de subculturas de demoscene o retrogaming .
  • Código que debe interactuar directamente con el hardware, por ejemplo, en controladores de dispositivos y manejadores de interrupciones .
  • En un procesador integrado o DSP, las interrupciones de alta repetición requieren la menor cantidad de ciclos por interrupción, como una interrupción que ocurre 1000 o 10000 veces por segundo.
  • Programas que necesitan usar instrucciones específicas del procesador no implementadas en un compilador. Un ejemplo común es la instrucción de rotación bit a bit en el núcleo de muchos algoritmos de cifrado, así como la consulta de la paridad de un byte o el acarreo de 4 bits de una adición.
  • Se requiere un ejecutable independiente de tamaño compacto que debe ejecutarse sin recurrir a los componentes de tiempo de ejecución o bibliotecas asociadas con un lenguaje de alto nivel. Los ejemplos han incluido firmware para teléfonos, sistemas de encendido y combustible de automóviles, sistemas de control de aire acondicionado, sistemas de seguridad y sensores.
  • Programas con bucles internos sensibles al rendimiento, donde el lenguaje ensamblador brinda oportunidades de optimización que son difíciles de lograr en un lenguaje de alto nivel. Por ejemplo, álgebra lineal con BLAS [41] [48] o transformación de coseno discreta (por ejemplo , versión de ensamblaje SIMD de x264 [49] ).
  • Programas que crean funciones vectorizadas para programas en lenguajes de nivel superior, como C. En el lenguaje de nivel superior, esto a veces es ayudado por funciones intrínsecas del compilador que se asignan directamente a los mnemónicos SIMD, pero sin embargo dan como resultado una conversión de ensamblaje uno a uno específico. para el procesador vectorial dado.
  • Programas en tiempo real como simulaciones, sistemas de navegación de vuelo y equipos médicos. Por ejemplo, en un sistema fly-by-wire , la telemetría se debe interpretar y actuar dentro de estrictas limitaciones de tiempo. Dichos sistemas deben eliminar las fuentes de demoras impredecibles, que pueden ser creadas por (algunos) lenguajes interpretados, recolección automática de basura , operaciones de paginación o multitarea preventiva . Sin embargo, algunos lenguajes de nivel superior incorporan componentes de tiempo de ejecución e interfaces del sistema operativo que pueden introducir tales retrasos. La elección de lenguajes de ensamblaje o de nivel inferior para tales sistemas brinda a los programadores una mayor visibilidad y control sobre los detalles del procesamiento.
  • Algoritmos criptográficos que siempre deben tomar estrictamente el mismo tiempo para ejecutarse, evitando ataques de tiempo .
  • Modifique y amplíe el código heredado escrito para mainframe IBM. [50] [51]
  • Situaciones en las que se requiere un control total sobre el medio ambiente, en situaciones de seguridad extremadamente alta en las que nada se puede dar por sentado .
  • Virus informáticos , cargadores de arranque , ciertos controladores de dispositivos u otros elementos muy cercanos al hardware o al sistema operativo de bajo nivel.
  • Simuladores de conjuntos de instrucciones para monitoreo, rastreo y depuración donde la sobrecarga adicional se mantiene al mínimo.
  • Situaciones en las que no existe un lenguaje de alto nivel, en un procesador nuevo o especializado para el que no hay un compilador cruzado disponible.
  • Ingeniería inversa y modificación de archivos de programa como:
    • binarios existentes que pueden o no haber sido escritos originalmente en un lenguaje de alto nivel, por ejemplo, cuando se intenta recrear programas para los cuales el código fuente no está disponible o se ha perdido, o cuando se rompe la protección contra copia de software propietario.
    • Videojuegos (también denominados pirateo de ROM ), que es posible mediante varios métodos. El método más utilizado es alterar el código del programa a nivel del lenguaje ensamblador.

El lenguaje ensamblador todavía se enseña 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 herramienta, los conceptos subyacentes siguen siendo importantes. Temas fundamentales como aritmética binaria , asignación de memoria , procesamiento de pila , codificación de juegos de caracteres , procesamiento de interrupciones y compiladorEl diseño sería difícil de estudiar en detalle sin una comprensión de cómo funciona una computadora a nivel de hardware. Dado que el comportamiento de una computadora se define fundamentalmente por su conjunto de instrucciones, la forma lógica de aprender tales conceptos es estudiar un lenguaje ensamblador. La mayoría de las computadoras modernas tienen conjuntos de instrucciones similares. Por tanto, estudiar un solo lenguaje ensamblador es suficiente para aprender: I) los conceptos básicos; II) reconocer situaciones en las que el uso del lenguaje ensamblador podría ser apropiado; y III) para ver cuán eficiente se puede crear código ejecutable a partir de lenguajes de alto nivel. [dieciséis]

Aplicaciones típicas

  • El lenguaje ensamblador se usa generalmente en el código de inicio de un sistema, el código de bajo nivel que inicializa y prueba el hardware del sistema antes de iniciar el sistema operativo y, a menudo, se almacena en la ROM . ( BIOS en sistemas de PC compatibles con IBM y CP / M es un ejemplo).
  • El lenguaje ensamblador se usa a menudo para código de bajo nivel, por ejemplo, para núcleos de sistemas operativos , que no pueden depender de la disponibilidad de llamadas al sistema preexistentes y, de hecho, deben implementarlas para la arquitectura de procesador particular en la que se ejecutará el sistema.
  • Algunos compiladores traducen primero los lenguajes de alto nivel en ensamblador antes de compilar completamente, lo que permite ver el código ensamblador con fines de depuración y optimización.
  • Algunos compiladores para lenguajes de nivel relativamente bajo, como Pascal o C , permiten al programador incrustar el lenguaje ensamblador directamente en el código fuente (llamado ensamblado en línea ). Los programas que utilizan estas funciones pueden construir abstracciones utilizando un lenguaje ensamblador diferente en cada plataforma de hardware. El código portátil del sistema puede utilizar estos componentes específicos del procesador a través de una interfaz uniforme.
  • El lenguaje ensamblador es útil en ingeniería inversa . Muchos programas se distribuyen solo en forma de código de máquina, que es sencillo de traducir al lenguaje ensamblador por un desensamblador , pero más difícil de traducir a un lenguaje de nivel superior a través de un descompilador . Herramientas como el desensamblador interactivo hacen un uso extensivo del desmontaje para tal fin. Los piratas informáticos utilizan esta técnica para descifrar software comercial y los competidores para producir software con resultados similares de empresas competidoras.
  • El lenguaje ensamblador se usa para mejorar la velocidad de ejecución, especialmente en las primeras computadoras personales con capacidad de procesamiento y RAM limitadas.
  • Los ensambladores se pueden utilizar para generar bloques de datos, sin sobrecarga de lenguaje de alto nivel, a partir de código fuente formateado y comentado, para ser utilizados por otro código. [52] [53]

Ver también

  • Compilador
  • Comparación de ensambladores
  • Desensamblador
  • Hexadecimal
  • Set de instrucciones arquitectura
  • Little man computer : un modelo informático educativo con un lenguaje ensamblador de base 10
  • Picar
  • Lenguaje ensamblador mecanografiado

Notas

  1. ^ "Utilizado como meta-ensamblador, permite al usuario diseñar sus propios lenguajes de programación y generar procesadores para dichos lenguajes con un mínimo de esfuerzo".
  2. ^ Ésta es una de las dos formas redundantes de esta instrucción que operan de manera idéntica. El 8086 y varias otras CPU de finales de la década de 1970 / principios de la de 1980 tienen redundancias en sus conjuntos de instrucciones, porque era más sencillo para los ingenieros diseñar estas CPU (para que quepan en chips de silicio de tamaños limitados) con los códigos redundantes que eliminarlos (ver términos de indiferencia ). Cada ensamblador generará típicamente solo una de dos o más codificaciones de instrucciones redundantes, pero un desensamblador generalmente reconocerá cualquiera de ellas.
  3. ^ AMD fabricó CPU Intel 8086, 8088 y 80286 de segunda fuente, y quizás CPU 8080A y / o 8085A, bajo licencia de Intel, pero a partir del 80386, Intel se negó a compartir sus diseños de CPU x86 con nadie; AMD demandó por esto por incumplimiento de contrato, y AMD diseñó, fabricó y vendió CPU de la familia x86 de 32 y 64 bits sin la ayuda o el respaldo de Intel.
  4. ^ En 7070 Autocoder, una definición de macro es un programa generador de macro 7070 que llama el ensamblador; Autocoder proporciona macros especiales para que las utilicen los generadores de macros.
  5. ^ "La siguiente restricción o limitación menor está en vigor con respecto al uso de 1401 Autocoder al codificar instrucciones macro ..."

Referencias

  1. ^ a b "Lenguaje ensamblador" . Ensamblador de alto nivel para z / OS & z / VM & z / VSE Language Reference Versión 1 Release 6 . IBM . 2014 [1990]. SC26-4940-06.
  2. Saxon, James A .; Plette, William S. (1962). Programación del IBM 1401, un manual programado de autoinstrucción . Englewood Cliffs, Nueva Jersey, EE.UU .: Prentice-Hall . LCCN 62-20615 . (NB. Uso del término programa de montaje ).
  3. ^ "Asamblea: revisión" (PDF) . Ciencia computacional e ingeniería. Facultad de Ingeniería, Universidad Estatal de Ohio . 2016. Archivado (PDF) desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  4. ^ Archer, Benjamin (noviembre de 2016). Lenguaje ensamblador para estudiantes . North Charleston, Carolina del Sur, EE. UU .: CreateSpace Independent Publishing . ISBN 978-1-5403-7071-6. El lenguaje ensamblador también puede denominarse código máquina simbólico.
  5. ^ Kornelis, AF (2010) [2003]. "Ensamblador de alto nivel - descripción general de códigos de operación, directivas de ensamblador" . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  6. ^ "Instrucciones macro" . Ensamblador de alto nivel para z / OS & z / VM & z / VSE Language Reference Versión 1 Release 6 . IBM . 2014 [1990]. SC26-4940-06.
  7. ^ Wilkes, Maurice Vincent ; Wheeler, David John ; Gill, Stanley J. (1951). La preparación de programas para una computadora digital electrónica (Reprint 1982 ed.). Editores Tomash . ISBN 978-0-93822803-5. OCLC  313593586 .
  8. Fairhead, Harry (16 de noviembre de 2017). "Historia de los lenguajes informáticos - La década clásica, 1950" . Programador . Archivado desde el original el 2 de enero de 2020 . Consultado el 6 de marzo de 2020 .
  9. ^ "¿Cómo dependen los lenguajes ensambladores de los sistemas operativos?" . Stack Exchange . Stack Exchange Inc. 28 de julio de 2011. Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .(NB. Las llamadas al sistema a menudo varían, por ejemplo, para MVS frente a VSE frente a VM / CMS; los formatos binarios / ejecutables para diferentes sistemas operativos también pueden variar).
  10. ^ Daintith, John, ed. (2019). "meta-ensamblador" . Un diccionario de informática . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  11. ^ Xerox Data Systems (octubre de 1975). Xerox Meta-Symbol Sigma 5-9 Computer Language and Operations Reference Manual (PDF) . pag. vi . Consultado el 7 de junio de 2020 .
  12. ^ Sistemas informáticos Sperry Univac (1977). Referencia del programador del metaensamblador de sistemas informáticos Sperry Univac (MASM) (PDF) . Consultado el 7 de junio de 2020 .
  13. ^ "Cómo utilizar lenguaje ensamblador en línea en código C" . gnu.org . Consultado el 5 de noviembre de 2020 .
  14. ↑ a b c d Salomon, David (febrero de 1993) [1992]. Escrito en la Universidad Estatal de California, Northridge, California, EE. UU. Chivers, Ian D. (ed.). Ensambladores y cargadores (PDF) . Serie Ellis Horwood en Computadoras y sus aplicaciones (1 ed.). Chicester, West Sussex, Reino Unido: Ellis Horwood Limited / Simon & Schuster International Group . págs. 7, 237-238. ISBN  0-13-052564-2. Archivado (PDF) desde el original el 23 de marzo de 2020 . Consultado el 1 de octubre de 2008 . (xiv + 294 + 4 páginas)
  15. ^ Beck, Leland L. (1996). "2". Software del sistema: Introducción a la programación de sistemas . Addison Wesley .
  16. ↑ a b Hyde, Randall (septiembre de 2003) [30 de septiembre de 1996]. "Prólogo (" ¿Por qué alguien aprendería estas cosas? ") / Capítulo 12 - Clases y objetos". El arte del lenguaje ensamblador (2 ed.). Sin prensa de almidón . ISBN 1-886411-97-2. Archivado desde el original el 6 de mayo de 2010 . Consultado el 22 de junio de 2020 .Fe de erratas: [1] (928 páginas) [2] [3]
  17. ^ a b c d Manual del desarrollador de software de arquitectura Intel, volumen 2: referencia del conjunto de instrucciones (PDF) . 2 . Intel Corporation . 1999. Archivado desde el original (PDF) el 11 de junio de 2009 . Consultado el 18 de noviembre de 2010 .
  18. ^ Ferrari, Adam; Batson, Alan; Falta, Mike; Jones, Anita (19 de noviembre de 2018) [Primavera de 2006]. Evans, David (ed.). "Guía de montaje x86" . Ciencias de la Computación CS216: Representación de programas y datos. Universidad de Virginia . Archivado desde el original el 24 de marzo de 2020 . Consultado el 18 de noviembre de 2010 .
  19. ^ "El manual de arquitectura SPARC, versión 8" (PDF) . SPARC Internacional . 1992. Archivado desde el original (PDF) el 10 de diciembre de 2011 . Consultado el 10 de diciembre de 2011 .
  20. ^ Moxham, James (1996). "Intérprete ZINT Z80" . Códigos de operación Z80 para ZINT . Archivado desde el original el 24 de marzo de 2020 . Consultado el 21 de julio de 2013 .
  21. ^ Hyde, Randall . "Capítulo 8. MASM: Directivas y pseudo-opcodes" (PDF) . El arte de la programación informática . Archivado (PDF) desde el original el 24 de marzo de 2020 . Consultado el 19 de marzo de 2011 .
  22. ^ Usuarios de 1401 Autocoder . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  23. ^ Griswold, Ralph E. (1972). "Capítulo 1". La macro implementación de SNOBOL4 . San Francisco, California, Estados Unidos: WH Freeman and Company . ISBN 0-7167-0447-1.
  24. ^ "Macros (C / C ++), MSDN Library para Visual Studio 2008" . Microsoft Corp. 2012-11-16. Archivado desde el original el 24 de marzo de 2020 . Consultado el 22 de junio de 2010 .
  25. Kessler, Marvin M. (18 de diciembre de 1970). "* Concepto * Informe 14 - Implementación de Macros para Permitir Programación Estructurada en OS / 360" . Software MVS: Macros Concept 14 . Gaithersburg, Maryland, Estados Unidos: International Business Machines Corporation . Archivado desde el original el 24 de marzo de 2020 . Consultado el 25 de mayo de 2009 .
  26. ^ "La función del kit de herramientas de ensamblador de alto nivel aumenta la productividad del programador" . Cartas de anuncio . IBM. 1995-12-12. A95-1432.
  27. ^ "lenguaje ensamblador: definición y mucho más de Answers.com" . answers.com . Archivado desde el original el 8 de junio de 2009 . Consultado el 19 de junio de 2008 .
  28. Provinciano, Brian (17 de abril de 2005). "NESHLA: El ensamblador de alto nivel, código abierto, 6502 para el sistema de entretenimiento de Nintendo" . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  29. Dufresne, Steven (21 de agosto de 2018). "Kathleen Booth: ensamblar las primeras computadoras mientras se inventa el ensamblaje" . Archivado desde el original el 24 de marzo de 2020 . Consultado el 10 de febrero de 2019 .
  30. ^ a b Booth, Andrew Donald ; Britten, Kathleen Hylda Valerie (septiembre de 1947) [agosto de 1947]. Consideraciones generales en el diseño de una computadora digital electrónica de uso general (PDF) (2 ed.). Instituto de Estudios Avanzados, Princeton, Nueva Jersey, EE. UU .: Birkbeck College, Londres . Archivado (PDF) desde el original el 24 de marzo de 2020 . Consultado el 10 de febrero de 2019 . Las ideas no originales, contenidas en el siguiente texto, se han derivado de varias fuentes ... Sin embargo, se considera que se debe hacer un reconocimiento al Prof. John von Neumann y al Dr. Herman Goldstein por muchas fructíferas discusiones ...
  31. ^ Campbell-Kelly, Martin (abril de 1982). "El desarrollo de la programación informática en Gran Bretaña (1945 a 1955)". IEEE Annals of the History of Computing . 4 (2): 121-139. doi : 10.1109 / MAHC.1982.10016 . S2CID 14861159 . 
  32. Campbell-Kelly, Martin (1980). "Programación del EDSAC". IEEE Annals of the History of Computing . 2 (1): 7–36. doi : 10.1109 / MAHC.1980.10009 .
  33. ^ "1985 Computer Pioneer Award 'para programación en lenguaje ensamblador' David Wheeler" .
  34. ^ Wilkes, Maurice Vincent (1949). "El EDSAC - una máquina de calcular electrónica". Revista de instrumentos científicos . 26 (12): 385–391. Código bibliográfico : 1949JScI ... 26..385W . doi : 10.1088 / 0950-7671 / 26/12/301 .
  35. da Cruz, Frank (17 de mayo de 2019). "La calculadora de tambor magnético IBM 650" . Historia de la informática: una cronología de la informática. Universidad de Columbia . Archivado desde el original el 15 de febrero de 2020 . Consultado el 17 de enero de 2012 .
  36. Pettus, Sam (10 de enero de 2008). "SegaBase Volumen 6 - Saturno" . Archivado desde el original el 13 de julio de 2008 . Consultado el 25 de julio de 2008 .
  37. Kauler, Barry (9 de enero de 1997). Programación de sistemas y lenguaje ensamblador de Windows: Programación de bajo nivel de 16 y 32 bits para PC y Windows . Prensa CRC . ISBN 978-1-48227572-8. Consultado el 24 de marzo de 2020 . Siempre se debate sobre la aplicabilidad del lenguaje ensamblador en nuestro mundo de programación moderno.
  38. Hsieh, Paul (24 de marzo de 2020) [2016, 1996]. "Optimización de la programación" . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 . ... los cambios de diseño tienden a afectar el rendimiento más que ... uno no debe pasar directamente al lenguaje ensamblador hasta que ...
  39. ^ "Índice TIOBE" . Software TIOBE . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  40. ^ Rusling, David A. (1999) [1996]. "Capítulo 2 Conceptos básicos del software" . El kernel de Linux . Archivado desde el original el 24 de marzo de 2020 . Consultado el 11 de marzo de 2012 .
  41. ↑ a b Markoff, John Gregory (28 de noviembre de 2005). "Escribir el código más rápido, a mano, por diversión: una computadora humana sigue acelerando chips" . The New York Times . Seattle, Washington, Estados Unidos. Archivado desde el original el 23 de marzo de 2020 . Consultado el 4 de marzo de 2010 .
  42. ^ "Maldad de campo de bits" . hardwarebug.org . 2010-01-30. Archivado desde el original el 5 de febrero de 2010 . Consultado el 4 de marzo de 2010 .
  43. ^ "GCC hace un lío" . hardwarebug.org . 2009-05-13. Archivado desde el original el 16 de marzo de 2010 . Consultado el 4 de marzo de 2010 .
  44. ^ Hyde, Randall . "El Gran Debate" . Archivado desde el original el 16 de junio de 2008 . Consultado el 3 de julio de 2008 .
  45. ^ "El código fuente vuelve a fallar" . hardwarebug.org . 2010-01-30. Archivado desde el original el 2 de abril de 2010 . Consultado el 4 de marzo de 2010 .
  46. ^ Haga clic en Cliff; Goetz, Brian. "Un curso intensivo en hardware moderno" . Archivado desde el original el 24 de marzo de 2020 . Consultado el 1 de mayo de 2014 .
  47. ^ "Programación 68K en Fargo II" . Archivado desde el original el 2 de julio de 2008 . Consultado el 3 de julio de 2008 .
  48. ^ "BLAS Benchmark-August2008" . eigen.tuxfamily.org. 2008-08-01. Archivado desde el original el 24 de marzo de 2020 . Consultado el 4 de marzo de 2010 .
  49. ^ "x264.git / common / x86 / dct-32.asm" . git.videolan.org. 2010-09-29. Archivado desde el original el 4 de marzo de 2012 . Consultado el 29 de septiembre de 2010 .
  50. ^ Bosworth, Edward (2016). "Capítulo 1 - Por qué estudiar el lenguaje ensamblador" . www.edwardbosworth.com . Archivado desde el original el 24 de marzo de 2020 . Consultado el 1 de junio de 2016 .
  51. ^ https://www-01.ibm.com/servers/resourcelink/svc00100.nsf/pages/zOSV2R3sc236852/$file/idad500_v2r3.pdf
  52. ^ Paul, Matthias R. (2001) [1996], "Especificación y documentación de referencia para NECPINW" , NECPINW.CPI - controlador de cambio de página de códigos DOS para NEC Pinwriters (2.08 ed.), FILESPEC.TXT, NECPINW.ASM, EUROFONT. INC de NECPI208.ZIP, archivada desde el original, el 10/09/2017 , recuperado 22/04/2013
  53. Paul, Matthias R. (13 de mayo de 2002). "[fd-dev] mkeyb" . freedos-dev . Archivado desde el original el 10 de septiembre de 2018 . Consultado el 10 de septiembre de 2018 .

Lectura adicional

  • Bartlett, Jonathan (2004). Programación desde cero: una introducción a la programación utilizando el lenguaje ensamblador de Linux . Bartlett Publishing . ISBN 0-9752838-4-7. Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 . [4]
  • Britton, Robert (2003). Programación en lenguaje ensamblador MIPS . Prentice Hall . ISBN 0-13-142044-5.
  • Calingaert, Peter (1979) [5 de noviembre de 1978]. Escrito en la Universidad de Carolina del Norte en Chapel Hill . Horowitz, Ellis (ed.). Ensambladores, compiladores y traducción de programas . Serie de ingeniería de programas informáticos (1ª edición, 1ª ed.). Potomac, Maryland, EE. UU .: Computer Science Press, Inc. ISBN 0-914894-23-4. ISSN  0888-2088 . LCCN  78-21905 . Consultado el 20 de marzo de 2020 . (2 + xiv + 270 + 6 páginas)
  • Duntemann, Jeff (2000). Lenguaje ensamblador paso a paso . Wiley . ISBN 0-471-37523-3.
  • Kann, Charles W. (2015). "Introducción a la programación en lenguaje ensamblador MIPS" . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  • Kann, Charles W. (2021). " Introducción a la programación en lenguaje ensamblador: de la sopa a las nueces: edición ARM "
  • Norton, Peter ; Socha, John (1986). Libro de lenguaje ensamblador de Peter Norton para IBM PC . Nueva York, Estados Unidos: Brady Books.
  • Cantante, Michael (1980). PDP-11. Programación en lenguaje ensamblador y organización de máquinas . Nueva York, Estados Unidos: John Wiley & Sons .
  • Sweetman, Dominic (1999). Consulte Ejecutar MIPS . Editores Morgan Kaufmann . ISBN 1-55860-410-3.
  • Waldron, John (1998). Introducción a la programación en lenguaje ensamblador RISC . Addison Wesley . ISBN 0-201-39828-1.
  • Yurichev, Dennis (4 de marzo de 2020) [2013]. "Comprensión del lenguaje ensamblador (ingeniería inversa para principiantes)" (PDF) . Archivado (PDF) desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  • "Libro de la comunidad MAPE" . 2009. Archivado desde el original el 30 de mayo de 2013 . Consultado el 30 de mayo de 2013 . ("Un libro en línea lleno de información útil sobre ASM, tutoriales y ejemplos de código" de la comunidad de ASM, archivado en el archivo de Internet).

Enlaces externos

  • Lenguaje ensamblador en Curlie
  • Programación en lenguaje ensamblador Unix
  • Ensamblaje de Linux
  • PPR: aprendizaje del lenguaje ensamblador
  • NASM - The Netwide Assembler (un lenguaje ensamblador popular)
  • Ejemplos de programación en lenguaje ensamblador
  • Creación de aplicaciones de Windows en lenguaje ensamblador
  • Consejos para la optimización del ensamblaje de Mark Larson
  • La tabla para lenguaje ensamblador a código de máquina