stringtranslate.com

lenguaje ensamblador

En programación de computadoras , el lenguaje ensamblador (alternativamente lenguaje ensamblador [1] o código de máquina simbólico ), [2] [3] [4] a menudo denominado simplemente ensamblador y comúnmente abreviado como ASM o asm , es cualquier lenguaje de programación de bajo nivel con una correspondencia muy fuerte entre las instrucciones del lenguaje y las instrucciones del código de máquina de la arquitectura . [5] El lenguaje ensamblador generalmente tiene una declaración por instrucción de máquina (1:1), pero las constantes, comentarios , directivas de ensamblador , [6] etiquetas simbólicas de, por ejemplo, ubicaciones de memoria , registros y macros [7] [1] generalmente son también apoyado.

El primer código ensamblador en el que se utiliza un lenguaje para representar instrucciones de código de máquina se encuentra en el trabajo de 1947 de Kathleen y Andrew Donald Booth , Coding for ARC . [8] El código ensamblador se convierte en código de máquina ejecutable mediante un programa de utilidad denominado ensamblador . El término "ensamblador" se atribuye generalmente a Wilkes , Wheeler y Gill en su libro de 1951 The Preparation of Programs for an Electronic Digital Computer , [9] quienes, sin embargo, usaron el término para significar "un programa que ensambla otro programa que consta de varios secciones en un solo programa". [10] El proceso de conversión se conoce como ensamblaje , como ensamblar el código fuente . El paso computacional cuando un ensamblador está procesando un programa se llama tiempo de ensamblaje .

Debido a que el ensamblador depende de las instrucciones del código de máquina, cada lenguaje ensamblador [nb 1] es específico de una arquitectura de computadora en particular . [11] [12] [13]

A veces hay más de un ensamblador para la misma arquitectura y, a veces, un ensamblador es específico de un sistema operativo o de sistemas operativos concretos. La mayoría de los 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, [nb 2] ya que el lenguaje proporciona acceso a todas las capacidades reales del procesador , sobre las cuales se basan todos los mecanismos de llamadas del sistema. en definitiva descansar. A diferencia de los lenguajes ensambladores, la mayoría de los lenguajes de programación de alto nivel son generalmente portátiles en múltiples arquitecturas, pero requieren interpretación o compilación , tareas mucho más complicadas que el ensamblaje.

En las primeras décadas de la informática, era común que tanto la programación de sistemas como la programación de aplicaciones se realizaran completamente en lenguaje ensamblador. Si bien sigue siendo irremplazable para algunos propósitos, la mayor parte de la programación ahora se realiza en lenguajes compilados e interpretados de alto nivel. En " No Silver Bullet ", Fred Brooks resumió los efectos del abandono de la programación en lenguaje ensamblador: "Seguramente el golpe más poderoso para la productividad, confiabilidad y simplicidad del software ha sido el uso progresivo de lenguajes de alto nivel para la programación. La mayoría de los observadores Atribuimos ese desarrollo a al menos un factor de cinco en productividad, y con ganancias concomitantes en confiabilidad, simplicidad y comprensibilidad”. [14]

Hoy en día, es típico utilizar pequeñas cantidades de código en lenguaje ensamblador dentro de sistemas más grandes implementados en un lenguaje de nivel superior, por razones de rendimiento o para interactuar directamente con el hardware de maneras no soportadas por el lenguaje de nivel superior. Por ejemplo, poco menos del 2% de la versión 4.9 del código fuente del kernel de Linux está escrito en ensamblador; más del 97% está escrito en C. [15]

Sintaxis del lenguaje ensamblador

El lenguaje ensamblador utiliza un mnemotécnico para representar, por ejemplo, cada instrucción de máquina de bajo nivel o código de operación , cada directiva , normalmente también cada registro arquitectónico , bandera , etc. Algunos de los mnemotécnicos pueden estar integrados y otros definidos por el usuario. 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 programas y memoria, y pueden calcular expresiones para operandos. De este modo, los programadores se liberan de tediosos cálculos repetitivos y los programas ensambladores son mucho más legibles que el código de máquina. Dependiendo de la arquitectura, estos elementos también se pueden combinar 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 en la depuración .

Algunos están orientados a columnas, con campos específicos en columnas específicas; esto era muy común en las máquinas que utilizaban tarjetas perforadas en los años cincuenta y principios de los sesenta. Algunos ensambladores tienen sintaxis de forma libre, con campos separados por delimitadores, por ejemplo, puntuación, espacios en blanco . Algunos ensambladores son híbridos, con, por ejemplo, etiquetas en una columna específica y otros campos separados por delimitadores; esto se volvió más común que la sintaxis orientada a columnas en la década de 1960.

Terminología

Conceptos clave

Ensamblador

Un programa ensamblador crea código objeto traduciendo combinaciones de mnemónicos y sintaxis para operaciones y modos de direccionamiento a sus equivalentes numéricos. Esta representación normalmente incluye un código de operación (" código de operación ") así como otros bits y datos de control. El ensamblador también calcula expresiones constantes y resuelve nombres simbólicos para ubicaciones de memoria y otras entidades. [20] El uso de referencias simbólicas es una característica clave de los ensambladores, ya que ahorra cálculos tediosos y actualizaciones manuales de direcciones después de modificaciones del programa. La mayoría de los ensambladores también incluyen funciones de macro para realizar sustitución textual, por ejemplo, para generar secuencias cortas comunes de instrucciones 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 jump-sizing , [20] 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, previa solicitud. Otros pueden incluso realizar 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. [21]

Los ensambladores han estado disponibles desde la década de 1950, como el primer paso por encima del lenguaje de 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, siendo Speedcode quizás uno de los ejemplos más conocidos.

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

Número de pases

Hay dos tipos de ensambladores según la cantidad de pasos necesarios a través del código fuente (cuántas veces el ensamblador lee el código fuente) para producir el archivo objeto.

En ambos casos, el ensamblador debe poder determinar el tamaño de cada instrucción en las pasadas iniciales para poder calcular las direcciones de los símbolos posteriores. Esto significa que si el tamaño de una operación que hace referencia 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 un pase posterior o las erratas. En un ensamblador con optimización de mirilla , las direcciones se pueden recalcular 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 una sola pasada era el tamaño de la memoria y la velocidad de ensamblaje; a menudo, una segunda pasada requeriría almacenar la tabla de símbolos en la memoria (para manejar referencias directas ), rebobinar y releer el código 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 dicha relectura. La ventaja del ensamblador multipaso 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. [22]

Ejemplo: en el siguiente fragmento de código, un ensamblador de una sola pasada podría determinar la dirección de la referencia hacia atrás BKWD al ensamblar la declaración S2 , pero no podría determinar la dirección de la referencia directa FWD al ensamblar la declaració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 se conocerían al generar código en el paso 2.

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

ensambladores de alto nivel

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

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

lenguaje ensamblador

Un programa escrito en lenguaje ensamblador consta de una serie de instrucciones mnemónicas del procesador y metadeclaraciones (conocidas como operaciones declarativas, directivas, pseudoinstrucciones, pseudooperaciones y pseudooperaciones), comentarios y datos. Las instrucciones en lenguaje ensamblador generalmente constan de un mnemotécnico de código de operación seguido de un operando , que puede ser una lista de datos, argumentos o parámetros. [24] Algunas instrucciones pueden estar "implícitas", lo que significa que los datos sobre los cuales opera la instrucción están definidos implícitamente por la instrucción misma; dicha instrucción no requiere 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 indica 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 utilizar. El identificador del registro AL es 000, por lo que el siguiente código de máquina carga el registro AL con los datos 01100001. [24]

10110000 01100001

Este código informático binario se puede hacer más legible para los 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 mnemotécnico 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.

MOVAL , 61h ;Cargue AL con 97 decimales (61 hexadecimales)   

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

Si se utiliza el mismo mnemónico para diferentes instrucciones, eso significa que el mnemónico corresponde a varios códigos de instrucción binaria diferentes, excluyendo los 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 Intel MOV AL, AHrepresenta una instrucción que mueve el contenido del registro AH al registro AL . La forma hexadecimal [nb 3] 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, está codificado (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 mnemotécnico 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 B0se puede aplicar la instrucción. 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 binaria), por lo que solo se 88puede aplicar la instrucción.

Los lenguajes ensambladores siempre están diseñados para que este tipo de falta de ambigüedad se aplique universalmente mediante 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 otro modo 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 de lenguaje ensamblador para estos. [24]

MOVAL , 1h ;Carga AL con valor inmediato 1 MOV CL , 2h ; Carga 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. [25]

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

En cada caso, el mnemotécnico 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. [24]

Transformar el lenguaje ensamblador en código de máquina es 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 declaraciones ensambladoras simples e instrucciones en lenguaje de máquina. Sin embargo, en algunos casos, un ensamblador puede proporcionar pseudoinstrucciones (esencialmente macros) que se expanden a 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 "bifurcarse si es mayor o igual", un ensamblador puede proporcionar una pseudoinstrucción que se expanda a las instrucciones "establecer si es menor que" y "bifurcarse si es cero (según el resultado de la instrucción establecer)" de la máquina. . La mayoría de los ensambladores con todas las funciones también proporcionan un rico lenguaje de macros (que se analiza a continuación) que utilizan los proveedores y programadores para generar código y secuencias de datos más complejos. Dado que la información sobre pseudoinstrucciones y macros definidas en el entorno 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 reales de la máquina 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 en 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 la cantidad y tipo de operaciones que admiten, en los diferentes tamaños y cantidades 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 de lenguaje ensamblador para un solo conjunto de instrucciones, generalmente instanciadas en diferentes programas ensambladores. En estos casos el más popular suele ser el que proporciona el fabricante de la CPU y se utiliza en su documentación.

Dos ejemplos de CPU que tienen dos conjuntos diferentes de mnemónicos son la familia Intel 8080 y la Intel 8086/8088. Debido a que Intel reclamó derechos de autor sobre sus mnemónicos en lenguaje ensamblador (en cada página de su documentación publicada en los años 1970 y principios de los 1980, al menos), algunas empresas que producían de forma independiente CPU compatibles con los conjuntos de instrucciones de Intel inventaron sus propios mnemónicos. 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 sólo para las nuevas instrucciones sino también para todas las instrucciones del 8080A. Por ejemplo, donde 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 son las CPU NEC V20 y V30 , copias mejoradas de Intel 8086 y 8088, respectivamente. Al igual que Zilog con el Z80, NEC inventó nuevos mnemotécnicos para todas las instrucciones 8086 y 8088, para evitar acusaciones de infracción de los derechos de autor de Intel. (Es cuestionable si dichos derechos de autor pueden ser válidos, y posteriormente compañías de CPU como AMD [nb 4] y Cyrix volvieron a publicar los mnemotécnicos de instrucciones x86/IA-32 de Intel exactamente sin permiso ni sanción legal.) Es dudoso que en la práctica muchas personas quién programó el V20 y el V30 en realidad escribió en el lenguaje ensamblador de NEC en lugar del de Intel; Dado que dos lenguajes ensambladores para la misma arquitectura de conjunto de instrucciones son isomórficos (algo así como el inglés y el latín Pig ), no es necesario utilizar el lenguaje ensamblador publicado por el propio fabricante con los productos de ese fabricante.

Diseño de lenguaje

Elementos basicos

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 una mnemónica de máquina o una mnemónica extendida 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 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 única 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 normalmente consta de una operación u 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 a 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 direcciones de 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 mnemotécnicos extendidos se usan a menudo para especificar una combinación de un código de operación con un operando específico, por ejemplo, los ensambladores de System/360 usan Bcomo mnemotécnico extendido para BCcon una máscara de 15 y NOP("NO OPeración" – no hacer nada en un paso) para BCcon una máscara de 0.

Los mnemotécnicos 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 sí tienen instrucciones que pueden usarse para ese propósito. En las CPU 8086, la instrucción se usa para , siendo un pseudocó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 utilizan los mnemónicos extendidos y para y con máscaras cero. Para la arquitectura SPARC, estas se conocen como instrucciones sintéticas . [26]xchg ax,axnopnopxchg ax,axxchg ax,axnopNOPNOPRBCBCR

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 se genera ld l,cseguida de ld h,b. [27] A veces se les conoce como pseudocódigos de operación .

Los mnemotécnicos son símbolos arbitrarios; En 1985, el IEEE publicó el Estándar 694 para un conjunto uniforme de mnemotécnicos 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 que contengan 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 pseudooperaciones.

Directivas de montaje

Las directivas de ensamblaje, también llamadas pseudocódigos de operación, pseudooperaciones o pseudooperaciones, son comandos dados a un ensamblador "que le indica que realice operaciones distintas a las instrucciones de ensamblaje". [20] Las directivas afectan el funcionamiento del 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 pseudocódigo de operación se reserva para directivas que generan código objeto, como las que generan datos. [28]

Los nombres de las pseudooperaciones suelen comenzar con un punto para distinguirlas de las instrucciones de la máquina. Las pseudooperaciones pueden hacer que el ensamblaje del programa dependa de los parámetros ingresados ​​por un programador, de modo que un programa pueda ensamblarse de diferentes maneras, tal vez para diferentes aplicaciones. O bien, se puede utilizar una pseudooperación para manipular la presentación de un programa para facilitar su lectura y mantenimiento. Otro uso común de las pseudooperaciones es reservar áreas de almacenamiento para datos en tiempo de ejecución y, opcionalmente, inicializar su contenido con 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 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 compensaciones dentro de 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 agregar comentarios al código fuente del programa que serán ignorados durante el ensamblado. Los comentarios juiciosos son esenciales en los programas en lenguaje ensamblador, ya que el significado y el propósito de una secuencia de instrucciones binarias de máquina pueden ser difíciles de determinar. El lenguaje ensamblador "sin formato" (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 redefinibles repetidamente) que involucran secuencias de líneas de texto en las que se incrustan variables y constantes. La definición de macro suele ser [nb 5] una mezcla de declaraciones en ensamblador, por ejemplo, directivas, instrucciones simbólicas de máquina y plantillas para declaraciones en 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, se puede utilizar su nombre en lugar de un mnemotécnico. Cuando el ensamblador procesa dicha 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 macro existente en el texto de reemplazo). . Las macros en este sentido datan de los codificadores automáticos de IBM de la década de 1950. [29]

Los ensambladores de macros suelen tener directivas para, por ejemplo, definir macros, definir variables, establecer variables como resultado de una expresión aritmética, lógica o de cadena, iterar y generar código condicionalmente. Algunas de esas directivas pueden estar restringidas para su uso dentro de una definición de macro, por ejemplo, MEXIT en HLASM , mientras que otras pueden permitirse dentro de código abierto (fuera de definiciones de macro), por ejemplo, AIF y COPY en HLASM.

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 normalmente se usa para crear macros cortas de una sola línea. Las instrucciones de macro del ensamblador, como las macros en PL/I y algunos otros lenguajes, pueden ser "programas" largos por sí mismas, ejecutadas mediante interpretación por parte del ensamblador durante el ensamblaje.

Dado que las macros pueden tener nombres "cortos" pero expandirse a varias o incluso muchas líneas de código, se pueden usar para hacer que los programas en lenguaje ensamblador parezcan mucho más cortos y requieran 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 ensambladores, opcionalmente introducir código de depuración integrado 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 permitiendo que las macros guarden contexto o intercambien información. . Por lo tanto, una macro podría 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 registro o bucles " desenrollados ", por ejemplo, o podría generar algoritmos completos basados ​​en parámetros complejos. Por ejemplo, una macro de "clasificación" podría aceptar la especificación de una clave de clasificación compleja y generar código diseñado para esa clave específica, sin necesitar las pruebas en tiempo de ejecución que serían necesarias para un procedimiento general que interpreta la especificación. Se puede considerar que una organización que utiliza un lenguaje ensamblador que se ha ampliado en gran medida utilizando un conjunto de macros de este tipo está trabajando en un lenguaje de nivel superior, ya que dichos programadores no están trabajando con los elementos conceptuales de nivel más bajo de una computadora. Subrayando este punto, se utilizaron macros para implementar una de las primeras máquinas virtuales en SNOBOL4 (1967), que fue escrita 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 utilizando un ensamblador de macros . [30] Esto permitió un alto grado de portabilidad para la época.

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 al crear versiones específicas de los sistemas operativos del fabricante. Esto lo hicieron, por ejemplo, programadores de sistemas que trabajaban con el Sistema de Monitor 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 . el sistema financiero/aéreo que comenzó en la década de 1970 y que aún hoy ejecuta muchos grandes sistemas de reservas por computadora (CRS) y sistemas de tarjetas de crédito.

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 operadores de tiempo de ensamblaje. indicando al ensamblador 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 un flujo de trabajo para construir el sistema, incluido el lenguaje de control de trabajos y las declaraciones de control de servicios públicos .

Esto se debe a que, como se comprendió en la década de 1960, el concepto de "procesamiento macro" es independiente del concepto de "ensamblaje", siendo el primero en términos modernos más procesamiento de textos, 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 macroprocesadores anteriores dentro de ensambladores, el preprocesador de C no es Turing completo porque carece de la capacidad de realizar un bucle o "ir a", lo que permite que los programas realicen un bucle.

A pesar del poder del procesamiento de macros, cayó en desuso en muchos lenguajes de alto nivel (con las principales excepciones C , C++ y PL/I), aunque siguió siendo un elemento perenne para los ensambladores.

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

foo: macro acargar a*b

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

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 fue el conjunto de macros Concept-14, [32] propuesto originalmente por Harlan Mills (marzo de 1970) e implementado por Marvin Kessler en la División de Sistemas Federales de IBM, que proporcionaba IF/ELSE/ENDIF y flujos de control similares. bloques para programas ensambladores de OS/360. Esta era 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). El High Level Assembler Toolkit de IBM [33] incluye dicho paquete de macros.

Un diseño curioso fue A-Natural, un ensamblador "orientado a flujos" para procesadores 8080/ Z80 [34] de Whitesmiths Ltd. (desarrolladores del sistema operativo Idris , similar a Unix , y lo que se informó que era el primer compilador comercial de C ). El lenguaje se clasificó como ensamblador porque trabajaba con elementos de máquina sin procesar, como códigos de operación , registros y 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 creó como lenguaje objeto de un compilador de C, en lugar de para codificación manual, pero su sintaxis lógica ganó algunos seguidores.

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

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

incluir \ masm32 \ incluir \ masm32rt.inc ; utilizar la biblioteca Masm32 .code demomain: REPETIR 20 cambiar rv ( nrandom , 9 ) ; generar un número entre 0 y 8 mov ecx , 7 case 0 print "case 0" case ecx ; a diferencia de la mayoría de los otros lenguajes de programación, imprima "caso 7" ; el switch Masm32 permite "casos variables" caso 1 .. 3 .if eax == 1 print "caso 1" .elseif eax == 2 print "caso 2" .else print "casos 1 a 3: otros" .endif caso 4 , 6 , 8 print "casos 4, 6 u 8" predeterminado mov ebx , 19 ; imprimir 20 estrellas . Repetir imprimir "*" dec ebx . ¿Hasta firmar? ; bucle hasta que se establezca el indicador de signo termina w print chr$ ( 13 , 10 ) ENDM salir fin demomain                                  

Uso del lenguaje ensamblador.

Perspectiva historica

Los lenguajes ensambladores no estaban disponibles en el momento en que se introdujo la computadora con programas almacenados . A Kathleen Booth "se le atribuye la invención del lenguaje ensamblador" [37] [38] basándose 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 marido) con el matemático John von. Neumann y el físico Herman Goldstine en el Instituto de Estudios Avanzados . [38] [39]

A finales de 1948, la Calculadora automática de almacenamiento con retardo electrónico (EDSAC) tenía un ensamblador (llamado "órdenes iniciales") integrado en su programa de arranque . Utilizó mnemónicos de una letra desarrollados por David Wheeler , a quien la IEEE Computer Society acredita como el creador del primer "ensamblador". [20] [40] [41] Los informes sobre la EDSAC introdujeron el término "ensamblaje" para el proceso de combinar campos en una palabra de instrucción. [42] SOAP ( Programa de ensamblaje óptimo simbólico ) era un lenguaje ensamblador para la computadora IBM 650 escrito por Stan Poley en 1955. [43]

Los lenguajes ensambladores eliminan gran parte de la programación de primera generación , propensa a errores, tediosa y que consume mucho tiempo, necesaria con las primeras computadoras, liberando a los programadores del tedio como recordar códigos numéricos y calcular direcciones. Alguna vez fueron ampliamente utilizados para todo tipo de programación. Sin embargo, a finales de la década de 1950, [44] su uso había sido suplantado en gran medida por lenguajes de nivel superior, en la búsqueda de una mayor productividad de la programación . [ cita necesaria ] Hoy en día, el lenguaje ensamblador todavía se usa para la manipulación directa del hardware, el acceso a instrucciones especializadas del procesador o para abordar problemas críticos de rendimiento. [45] Los usos típicos son controladores de dispositivos , sistemas integrados de bajo nivel y sistemas en tiempo real (ver § Uso actual).

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 íntegramente 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 IBM escrito por grandes corporaciones. COBOL , FORTRAN y algunos PL/I eventualmente desplazaron gran parte de este trabajo, aunque varias organizaciones grandes conservaron infraestructuras de aplicaciones en lenguaje ensamblador hasta bien entrada la década de 1990.

El lenguaje ensamblador ha sido durante mucho tiempo el principal lenguaje de desarrollo para computadoras domésticas de 8 bits, como la familia Atari de 8 bits , Apple II , MSX , ZX Spectrum y Commodore 64 . Los dialectos BÁSICOS interpretados en estos sistemas ofrecen una velocidad de ejecución insuficiente y facilidades insuficientes para aprovechar al máximo el hardware disponible. Estos sistemas tienen graves limitaciones de recursos, memoria idiosincrásica y arquitecturas de visualización, y proporcionan servicios de sistema limitados. También existen pocos compiladores de lenguajes de alto nivel adecuados para uso en microcomputadoras. De manera similar, el lenguaje ensamblador es la opción predeterminada para consolas de 8 bits como Atari 2600 y Nintendo Entertainment System .

El software clave para PC compatibles con IBM se escribió en lenguaje ensamblador, como MS-DOS , Turbo Pascal y la hoja de cálculo Lotus 1-2-3 . A medida que la velocidad de la computadora creció exponencialmente, el lenguaje ensamblador se convirtió en una herramienta para acelerar partes de programas, como la representación de Doom , en lugar de un lenguaje de desarrollo dominante. En la década de 1990, el lenguaje ensamblador se usaba para obtener rendimiento de sistemas como Sega Saturn [46] y como lenguaje principal para hardware arcade basado en la CPU/GPU integrada TMS34010 , como Mortal Kombat y NBA Jam .

Uso actual

Ha habido debate sobre la utilidad y el rendimiento del lenguaje ensamblador en relación con los lenguajes de alto nivel. [47]

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

En julio de 2017 , el índice TIOBE de popularidad de lenguajes de programación clasifica al lenguaje ensamblador en el puesto 11, por delante de Visual Basic , por ejemplo. [49] 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 que los compiladores de optimización modernos [50] convierten 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. [51] [52] [53] La complejidad de los procesadores y subsistemas de memoria modernos hace que la optimización efectiva sea cada vez más difícil para los compiladores, así como para los programadores de ensamblaje. [54] [55] Además, el aumento del rendimiento del procesador ha significado que la mayoría de las CPU permanecen inactivas la mayor parte del tiempo, [56] con retrasos causados ​​por cuellos de botella predecibles, como errores 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 lenguaje ensamblador:

El lenguaje ensamblador todavía se enseña en la mayoría de los programas de informática 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 la aritmética binaria , la asignación de memoria , el procesamiento de pilas , la codificación de juegos de caracteres , el procesamiento de interrupciones y el diseño de compiladores serían difíciles de estudiar en detalle sin comprender cómo opera una computadora a nivel de hardware. Dado que el comportamiento de una computadora está definido 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 lo tanto, estudiar un solo lenguaje ensamblador es suficiente para aprender: I) los conceptos básicos; II) reconocer situaciones donde el uso del lenguaje ensamblador podría ser apropiado; y III) ver cómo se puede crear código ejecutable eficiente a partir de lenguajes de alto nivel. [23]

Aplicaciones Típicas

Ver también

Notas

  1. ^ Aparte de los metaensambladores
  2. ^ Sin embargo, eso no significa que los programas ensambladores que implementan esos lenguajes sean universales.
  3. ^ Esta es una de las dos formas redundantes de esta instrucción que funcionan de manera idéntica. El 8086 y varias otras CPU de finales de los años 1970 y principios de los 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 que no me importan ). Normalmente, cada ensamblador generará sólo una de dos o más codificaciones de instrucciones redundantes, pero un desensamblador normalmente reconocerá cualquiera de ellas.
  4. ^ AMD fabricó CPU Intel 8086, 8088 y 80286 de segunda fuente, y quizás CPU 8080A y 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 ni el respaldo de Intel.
  5. ^ En 7070 Autocoder, una definición de macro es un programa generador de macros 7070 al que llama el ensamblador; Autocoder proporciona macros especiales para que las utilicen los generadores de macros.

Referencias

  1. ^ ab "Lenguaje ensamblador". Ensamblador de alto nivel para z/OS & z/VM & z/VSE Language Reference Versión 1 Versión 6. IBM . 2014 [1990]. SC26-4940-06.
  2. ^ "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 .
  3. ^ 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 de máquina simbólico.
  4. ^ Streib, James T. (2020). "Guía de lenguaje ensamblador". Temas de Pregrado en Ciencias de la Computación . Cham: Editorial Internacional Springer. doi :10.1007/978-3-030-35639-2. ISBN 978-3-030-35638-5. ISSN  1863-7310. S2CID  195930813. Programar en lenguaje ensamblador tiene los mismos beneficios que programar en lenguaje de máquina, excepto que es más fácil.
  5. ^ Sajón, James A.; Plette, William S. (1962). Programación del IBM 1401, un manual programado de autoinstrucción. Englewood Cliffs, Nueva Jersey, Estados Unidos: Prentice-Hall . LCCN  62-20615.(NB. Uso del término programa de montaje .)
  6. ^ Kornelis, AF (2010) [2003]. "Ensamblador de alto nivel: descripción general de códigos de operación, directivas del ensamblador". Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  7. ^ "Macroinstrucciones". Ensamblador de alto nivel para z/OS & z/VM & z/VSE Language Reference Versión 1 Versión 6. IBM . 2014 [1990]. SC26-4940-06.
  8. ^ Stand, Andrew D; Britten, Kathleen HV (1947). Codificación para ARC (PDF) . Instituto de Estudios Avanzados, Princeton . Consultado el 4 de noviembre de 2022 .
  9. ^ Wilkes, Maurice Vicente ; Wheeler, David Juan ; Gill, Stanley J. (1951). La preparación de programas para una computadora digital electrónica (Reimpresión 1982 ed.). Editores Tomash . ISBN 978-0-93822803-5. OCLC  313593586.
  10. ^ Fairhead, Harry (16 de noviembre de 2017). "Historia de los lenguajes informáticos: la década clásica, década de 1950". Yo programador . Archivado desde el original el 2020-01-02 . Consultado el 6 de marzo de 2020 .
  11. ^ "¿Cómo dependen los lenguajes ensambladores de los sistemas operativos?". Intercambio de pila . 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 , VSE o VM/CMS; los formatos binarios/ejecutables para diferentes sistemas operativos también pueden variar).
  12. ^ Austerlitz, Howard (2003). "Lenguajes de programación informática". Técnicas de adquisición de datos mediante PC . Elsevier. págs. 326–360. doi :10.1016/b978-012068377-2/50013-9. ISBN 9780120683772. El lenguaje ensamblador (o ensamblador) es un lenguaje informático compilado de bajo nivel. Depende del procesador ya que básicamente traduce los mnemotécnicos del ensamblador directamente en los comandos que entiende una CPU en particular, uno a uno. Estos mnemotécnicos del ensamblador son el conjunto de instrucciones para ese procesador.
  13. ^ Carnes, Beau (27 de abril de 2022). "Aprenda a programar en lenguaje ensamblador con ARM". freeCodeCamp.org . Consultado el 21 de junio de 2022 . El lenguaje ensamblador suele ser específico de una arquitectura informática particular, por lo que existen varios tipos de lenguajes ensambladores. ARM es un lenguaje ensamblador cada vez más popular.
  14. ^ Brooks, Federico P. (1986). "No hay una solución milagrosa: esencia y accidente en la ingeniería de software". Actas de la Décima Conferencia Mundial de Computación IFIP . págs. 1069-1076.
  15. ^ Anguiano, Ricardo. "Línea principal del kernel de Linux 4.9 sloccount.txt". Esencia . Consultado el 4 de mayo de 2022 .
  16. ^ Daintith, John, ed. (2019). "metaensamblador". Un diccionario de informática . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  17. ^ Xerox Data Systems (octubre de 1975). Manual de referencia de operaciones y lenguaje de computadoras Xerox Meta-Symbol Sigma 5-9 (PDF) . pag. vi. Archivado (PDF) desde el original el 9 de octubre de 2022 . Consultado el 7 de junio de 2020 . Utilizado como metaensamblador, permite al usuario diseñar sus propios lenguajes de programación y generar procesadores para dichos lenguajes con un mínimo de esfuerzo.
  18. ^ Sistemas informáticos Sperry Univac (1977). Referencia del programador del metaensamblador (MASM) de Sperry Univac Computer Systems (PDF) . Archivado (PDF) desde el original el 9 de octubre de 2022 . Consultado el 7 de junio de 2020 .
  19. ^ "Cómo utilizar el lenguaje ensamblador en línea en código C". gnu.org . Consultado el 5 de noviembre de 2020 .
  20. ^ abcd Salomon, David (febrero de 1993) [1992]. Escrito en la Universidad Estatal de California, Northridge, California, EE. UU. Chivers, Ian D. (ed.). Ensambladoras y Cargadoras (PDF) . Serie de Ellis Horwood sobre 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)
  21. ^ Finlayson, Ian; Davis, Brandon; Gavín, Pedro; Eh, Gang-Ryung; Whaley, David; Själander, Magnus; Tyson, Gary (2013). "Mejora de la eficiencia del procesador mediante la canalización estática de instrucciones". Actas de la 14ª conferencia ACM SIGPLAN/SIGBED sobre Lenguajes, compiladores y herramientas para sistemas integrados . págs. 33–44. doi :10.1145/2465554.2465559. ISBN 9781450320856. S2CID  8015812.
  22. ^ Beck, Leland L. (1996). "2". Software del sistema: una introducción a la programación de sistemas . Addison Wesley .
  23. ^ ab 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 .Erratas: [1] (928 páginas) [2][3]
  24. ^ abcd Manual del desarrollador de software de arquitectura Intel, volumen 2: referencia del conjunto de instrucciones (PDF) . vol. 2. Corporación Intel . 1999. Archivado desde el original (PDF) el 11 de junio de 2009 . Consultado el 18 de noviembre de 2010 .
  25. ^ Ferrari, Adán; Batson, Alan; Falta, Mike; Jones, Anita (19 de noviembre de 2018) [primavera de 2006]. Evans, David (ed.). "Guía de montaje x86". Informática 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 .
  26. ^ "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 .
  27. ^ 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 .
  28. ^ Hyde, Randall . "Capítulo 8. MASM: Directivas y pseudocódigos de operación" (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 .
  29. ^ Sistema de codificador automático 1401, programa n.º 1401-AU-037, versión 3, nivel de modificación 11 (PDF) . 1965-12-07 . Consultado el 21 de enero de 2024 . La siguiente restricción o limitación menor está vigente con respecto al uso de 1401 Autocoder al codificar instrucciones macro...
  30. ^ Griswold, Ralph E. (1972). "Capítulo 1". La macroimplementación de SNOBOL4 . San Francisco, California, Estados Unidos: WH Freeman and Company . ISBN 0-7167-0447-1.
  31. ^ "Macros (C/C++), biblioteca MSDN 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 .
  32. ^ Kessler, Marvin M. (18 de diciembre de 1970). "*Concepto* Informe 14 - Implementación de macros para permitir la programación estructurada en OS/360". Software MVS: Concepto 14 Macros . Gaithersburg, Maryland, EE. UU.: Corporación Internacional de Máquinas de Negocios . Archivado desde el original el 24 de marzo de 2020 . Consultado el 25 de mayo de 2009 .
  33. ^ "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. Archivado desde el original el 7 de marzo de 2023.
  34. ^ Whitesmiths Ltd (15 de julio de 1980). A-Manual de referencia del lenguaje natural.
  35. ^ "lenguaje ensamblador: definición y mucho más de Answers.com". respuestas.com . Archivado desde el original el 8 de junio de 2009 . Consultado el 19 de junio de 2008 .
  36. ^ Provinciano, Brian (17 de abril de 2005). "NESHLA: ensamblador 6502 de código abierto de alto nivel para Nintendo Entertainment System". Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  37. ^ 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 .
  38. ^ ab 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 multiuso (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 agradecer al Prof. John von Neumann y al Dr. Herman Goldstein por sus muchos y fructíferos discusiones...
  39. ^ Campbell-Kelly, Martin (abril de 1982). "El desarrollo de la programación informática en Gran Bretaña (1945 a 1955)". Anales IEEE de la historia de la informática . 4 (2): 121-139. doi :10.1109/MAHC.1982.10016. S2CID  14861159.
  40. ^ Campbell-Kelly, Martín (1980). "Programación del EDSAC: Actividad de programación temprana en la Universidad de Cambridge". Anales IEEE de la historia de la informática . 2 (1): 7–36. doi :10.1109/MAHC.1980.10009.
  41. ^ "Premio Computer Pioneer 1985 'Por programación en lenguaje ensamblador' David Wheeler". 2018-03-27.
  42. ^ Wilkes, Maurice Vicente (1949). "La EDSAC - una máquina calculadora 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.
  43. ^ 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 Colombia . Archivado desde el original el 15 de febrero de 2020 . Consultado el 17 de enero de 2012 .
  44. ^ Abell, John C. "15 de octubre de 1956: Fortran cambia para siempre la suerte de la informática". Cableado . ISSN  1059-1028 . Consultado el 2 de marzo de 2024 .
  45. ^ Collen, Morris F. (marzo-abril de 1994). "Los orígenes de la informática". Revista de la Asociación Estadounidense de Informática Médica . 1 (2): 96–97. doi :10.1136/jamia.1994.95236152. PMC 116189 . PMID  7719803. 
  46. ^ 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 .{{cite web}}: Mantenimiento CS1: URL no apta ( enlace )
  47. ^ 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 existe un debate sobre la aplicabilidad del lenguaje ensamblador en nuestro mundo de programación moderno.
  48. ^ 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 ...
  49. ^ "Índice TIOBE". Software TIOBE . Archivado desde el original el 24 de marzo de 2020 . Consultado el 24 de marzo de 2020 .
  50. ^ Rusling, David A. (1999) [1996]. "Capítulo 2: Conceptos básicos del software". El núcleo de Linux . Archivado desde el original el 24 de marzo de 2020 . Consultado el 11 de marzo de 2012 .
  51. ^ ab 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 los chips". Los New York Times . Seattle, Washington, Estados Unidos. Archivado desde el original el 23 de marzo de 2020 . Consultado el 4 de marzo de 2010 .
  52. ^ "Maldad del 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 .
  53. ^ "El CCG 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 .
  54. ^ Hyde, Randall . "El gran debate". Archivado desde el original el 16 de junio de 2008 . Consultado el 3 de julio de 2008 .
  55. ^ "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 .
  56. ^ Haga clic, acantilado; Goetz, Brian. "Un curso intensivo sobre hardware moderno". Archivado desde el original el 24 de marzo de 2020 . Consultado el 1 de mayo de 2014 .
  57. ^ "Programación de 68K en Fargo II". Archivado desde el original el 2 de julio de 2008 . Consultado el 3 de julio de 2008 .
  58. ^ "BLAS Benchmark-agosto de 2008". eigen.tuxfamily.org. 2008-08-01. Archivado desde el original el 24 de marzo de 2020 . Consultado el 4 de marzo de 2010 .
  59. ^ "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 .
  60. ^ "rav1e/README.md en v0.6.3". GitHub . Archivado desde el original el 22 de febrero de 2023 . Consultado el 21 de febrero de 2023 .
  61. ^ "README.md · 1.1.0 · VideoLAN / dav1d". 2023-02-13. Archivado desde el original el 22 de febrero de 2023 . Consultado el 21 de febrero de 2023 .
  62. ^ Bosworth, Eduardo (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 .
  63. ^ "Instrucciones de macro DFSMS de z/OS versión 2 versión 3 para conjuntos de datos" (PDF) . IBM. 2019-02-15. Archivado (PDF) desde el original el 25 de junio de 2021 . Consultado el 14 de septiembre de 2021 .
  64. ^ 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, archivado desde el original el 10 de septiembre de 2017 , consultado el 22 de abril de 2013
  65. ^ Paul, Matías 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 .

Otras lecturas

enlaces externos