1
2 3 LENGUAJE
bits no tenían operaciones para multiplicar o dividir nú- Son operaciones que mueven datos de un regis-
meros, por ejemplo, y había que hacer subrutinas para tro, desde y hacia un puerto; o de la memoria,
realizar esas operaciones. Otras CPU puede que no ten- desde y hacia un puerto
gan operaciones de punto flotante y habría que hacer o
conseguir bibliotecas que realicen esas operaciones. • INPUT Lectura desde un puerto de en-
Las instrucciones de la CPU pueden agruparse, de acuer- trada
do a su funcionalidad, en: • OUTPUT Escritura hacia un puerto de
Operaciones con enteros: (de 8, 16, 32 y 64 bits depen- salida
diendo de la arquitectura de la CPU, en los sistemas muy
viejos también de 12, 18, 24, 36 y 48 bits) Operaciones para el control del flujo del programa:
Estas son operaciones realizadas por la Unidad aritmético
lógica de la CPU • Llamadas y retornos de subrutinas
simplificar la programación. Por ejemplo, para un códi- instrucción MOV y el código del registro hacia donde se
go máquina condicional como “si X mayor o igual que”, va a mover el dato:
un ensamblador puede utilizar una pseudoinstrucción al 1011 0000 01100001 | | | | | +---- Número 61h en binario
grupo “haga si menor que”, y “si = 0” sobre el resultado | | | +--- Registro AL +-------- Instrucción MOV
de la condición anterior. Los Ensambladores más com-
pletos también proveen un rico lenguaje de macros que En el segundo byte se especifica el número 61h, escrito en
se utiliza para generar código más complejo y secuencias binario como 01100001, que se asignará al registro AL,
de datos. quedando la sentencia ejecutable como:
Para el mismo procesador y el mismo conjunto de ins-
trucciones de CPU, diferentes programas ensambladores • 10110000 01100001
pueden tener, cada uno de ellos, variaciones y diferencias
en el conjunto de mnemónicos o en la sintaxis de su len- La cual puede ser entendida y ejecutada directamente por
guaje ensamblador. Por ejemplo, en un lenguaje ensam- el procesador.
blador para la arquitectura x86, se puede expresar la ins-
trucción para mover 5 al registro AL de la siguiente ma-
nera: MOV AL, 5, mientras que para otro ensamblador 4 Diseño del lenguaje
para la misma arquitectura se expresaría al revés: MOV
5, AL. Ambos lenguajes ensambladores harían exacta-
mente lo mismo, solo que está expresado de manera di-
4.1 Elementos básicos
ferente. El primero usa la sintaxis de Intel, mientras que
Hay un grado grande de diversidad en la manera en que
el segundo usa la sintaxis de AT&T
los autores de los ensambladores categorizan las senten-
El uso del ensamblador no resuelve definitivamente el cias y en la nomenclatura que usan. En particular, al-
problema de cómo programar un sistema basado en mi- gunos describen cualquier cosa como pseudo-operación
croprocesador de modo sencillo ya que para hacer un (pseudo-Op), con excepción del mnemónico de máquina
uso eficiente del mismo, hay que conocer a fondo el o del mnemónico extendido.
microprocesador, los registros de trabajo de que dispone,
Un típico lenguaje ensamblador consiste en 3 tipos de
la estructura de la memoria, y muchas cosas más referen-
sentencias de instrucción que son usadas para definir las
tes a su estructura básica de funcionamiento.
operaciones del programa:
ej, el ensamblador del System/360 usa a B como un mne- Por ejemplo, las directivas pudieran ser usadas para re-
mónico extendido para el BC con una máscara de 15 y servar áreas de almacenamiento y opcionalmente su para
NOP al BC con una máscara de 0. asignar su contenido inicial. Los nombres de las directi-
Los mnemónicos extendidos son frecuentemente usados vas a menudo comienzan con un punto para distinguirlas
para soportar usos especializados de instrucciones, a me- de las instrucciones de máquina.
nudo para propósitos no obvios con respecto al nombre de Los ensambladores simbólicos le permiten a los progra-
la instrucción. Por ejemplo, muchos CPU no tienen una madores asociar nombres arbitrarios (etiquetas o símbo-
instrucción explícita de NOP (No Operación), pero tie- los) a posiciones de memoria. Usualmente, cada constan-
nen instrucciones que puedan ser usadas para tal propó- te y variable tiene un nombre para que las instrucciones
sito. En el CPU 8086, la instrucción XCHG AX,AX (in- pueden referir a esas ubicaciones por nombre, así promo-
tercambia el registro AX consigo mismo) es usada para el viendo el código autodocumentado. En el código ejecu-
NOP, con NOP siendo un pseudo-opcode para codificar table, el nombre de cada subprograma es asociado a su
la instrucción XCHG AX,AX. Algunos desensamblado- punto de entrada, así que cualquier llamada a un subpro-
res reconocen esto y decodificarán la instrucción XCHG grama puede usar su nombre. Dentro de subprogramas, a
AX,AX como NOP. Similarmente, los ensambladores de los destinos GOTO se le dan etiquetas. Algunos ensam-
IBM para el System/360 usan los mnemónicos extendi- bladores soportan símbolos locales que son léxicamente
dos NOP y NOPR con las máscaras cero para BC y BCR. distintos de los símbolos normales (ej, el uso de “10$"
Algunos ensambladores también soportan simples ma- como un destino GOTO).
croinstrucciones incorporadas que generan dos o más ins- La mayoría de los ensambladores proporcionan un mane-
trucciones de máquina. Por ejemplo, con algunos ensam- jo flexible de símbolos, permitiendo a los programadores
bladores para el Z80, la instrucción manejar diversos espacios de nombres, calcular automá-
ticamente offsets dentro de estructuras de datos, y asignar
LD HL, BC etiquetas que refieren a valores literales o al resultado de
cálculos simples realizados por el ensamblador. Las eti-
genera las instrucciones quetas también pueden ser usadas para inicializar cons-
tantes y variables con direcciones relocalizables.
LD L, C
LD H, B.[3] Los lenguajes ensambladores, como la mayoría de los
otros lenguajes de computador, permiten que comenta-
LD HL, BC es un pseudo-opcode, que en este caso simu- rios sean añadidos al código fuente, que son ignorados
la ser una instrucción de 16 bits, cuando se expande se por el programa ensamblador. El buen uso de los comen-
producen dos instrucciones de 8 bits que equivalen a la tarios es aún más importante con código ensamblador que
simulada de 16 bits. con lenguajes de alto nivel, pues el significado y el pro-
pósito de una secuencia de instrucciones es más duro de
descifrar a partir del código en sí mismo.
4.1.2 Secciones de datos
El uso sabio de estas facilidades puede simplificar gran-
Hay instrucciones usadas para definir elementos de datos demente los problemas de codificar y mantener el código
para manejar datos y variables. Definen el tipo de dato, la de bajo nivel. El código fuente de lenguaje ensamblador
longitud y la alineación de los datos. Estas instrucciones crudo generado por compiladores o desensambladores -
también pueden definir si los datos están disponibles para código sin ningún comentario, ni símbolos con algún sen-
programas exteriores (programas ensamblados separada- tido, ni definiciones de datos - es muy difícil de leer cuan-
mente) o solamente para el programa en el cual la sección do deben hacerse cambios.
de datos está definida. Algunos ensambladores clasifican
estas instrucción
4.2 Macros
4.3 Soporte para programación estructu- tadores, liberando a los programadores del tedio tal como
rada recordar códigos numéricos y cálculo de direcciones. Una
vez fueron ampliamente usados para todo tipo de pro-
Algunos ensambladores han incorporado elementos de gramación. Sin embargo, por los años 1980 (1990 en los
programación estructurada para codificar el flujo de la microcomputadores), su uso había sido en gran parte su-
ejecución. El ejemplo más temprano de este acercamien- plantado por los lenguajes de alto nivel,[cita requerida] en la
to estaba en el Concept-14 macro set, originalmente pro- búsqueda de una mejorada productividad en programa-
puesto por el Dr. H.D. Mills (marzo de 1970), e imple- ción. Hoy en día, aunque el lenguaje ensamblador es casi
mentado por Marvin Kessler en la Federal Systems Di- siempre manejado y generado por los compiladores, to-
vision de IBM, que extendió el macro ensamblador del davía se usa para la manipulación directa del hardware,
S/360 con bloques de control de flujo IF/ELSE/ENDIF y acceso a instrucciones especializadas del procesador, o
similares.[5] Esto era una manera de reducir o eliminar el para resolver problemas de desempeño crítico. Los usos
uso de operaciones GOTO en el código en lenguaje en- típicos son controladores/manejadores (drivers) de dispo-
samblador, uno de los principales factores que causaban sitivo, sistemas embebidos de bajo nivel, y sistemas de
código espagueti en el lenguaje ensamblador. Este acer- tiempo real.
camiento fue ampliamente aceptado a principios de los Históricamente, un gran número de programas han sido
años 1980 (los últimos días del uso de lenguaje ensam- escritos enteramente en lenguaje ensamblador. Los sis-
blador en gran escala). temas operativos fueron casi exclusivamente escritos en
Un curioso diseño fue A-natural, un ensamblador “orien- lenguaje ensamblador hasta la aceptación amplia del len-
tado a la corriente” (stream-oriented) para los procesado- guaje de programación C en los años 1970 y principios
res 8080/Z80[cita requerida] de Whitesmiths Ltd. (desarro- de los 1980. También, muchas aplicaciones comerciales
lladores del sistema operativo Idris, similar al Unix), y lo fueron escritas en lenguaje ensamblador, incluyendo una
que fue reportado como el primer compilador C comer- gran cantidad del software escrito por grandes corpora-
cial). El lenguaje fue clasificado como un ensamblador, ciones para mainframes de IBM. Los lenguajes COBOL
porque trabajaba con elementos de máquina crudos tales y FORTRAN eventualmente desplazaron mucho de es-
como opcodes, registros, y referencias de memoria; pe- te trabajo, aunque un número de organizaciones grandes
ro incorporaba una sintaxis de expresión para indicar el conservaran las infraestructuras de aplicaciones en len-
orden de ejecución. Los paréntesis y otros símbolos es- guaje ensamblador hasta bien entrados los años 1990.
peciales, junto con construcciones de programación es- La mayoría de los primeros microcomputadores confia-
tructurada orientadas a bloques, controlaban la secuencia ron en el lenguaje ensamblador codificado a mano, inclu-
de las instrucciones generadas. A-natural fue construido yendo la mayoría de los sistemas operativos y de las apli-
como el lenguaje objeto de un compilador C, en vez de la caciones grandes. Esto era porque estos sistemas tenían
codificación manual, pero su sintaxis lógica ganó algunos limitaciones severas de recursos, impusieron idiosincráti-
seguidores. cas arquitecturas de memoria y de pantalla, y proporcio-
Ha habido poca demanda aparente para ensambladores naron servicios de sistema limitados y con errores. Quizás
más sofisticados debido a la declinación del desarrollo de más importante era la falta de compiladores de primera
lenguaje ensamblador de larga escala.[6] A pesar de eso, clase de lenguajes de alto nivel adecuados para el uso en
todavía se están desarrollando y aplicando en casos donde el microcomputador. Un factor psicológico también pudo
las limitaciones de recursos o las particularidades en la haber jugado un papel: la primera generación de progra-
arquitectura de sistema objetivo previenen el efectivo uso madores de los microcomputadores conservó una actitud
de lenguajes de alto nivel.[7] de aficionado de “alambres y alicates”.
En un contexto más comercial, las más grandes razones
para usar el lenguaje ensamblador era hacer programas
con mínimo tamaño, mínima sobrecarga, mayor veloci-
5 Uso del lenguaje ensamblador dad y confiabilidad.
Los típicos ejemplos de programas grandes en lenguaje
5.1 Perspectiva histórica ensamblador de ese tiempo son los sistemas operativos
IBM PC DOS y aplicaciones tempranas tales como la
Los lenguajes ensambladores fueron primero desarro- hoja de cálculo Lotus 1-2-3, y casi todos los juegos popu-
llados en los años 1950, cuando fueron referidos como lares para la familia Atari 800 de computadores persona-
lenguajes de programación de segunda generación. Por les. Incluso en los años 1990, la mayoría de los videojue-
ejemplo, el SOAP (Symbolic Optimal Assembly Pro- gos de consola fueron escritos en ensamblador, incluyen-
gram) era un lenguaje ensamblador de 1957 para el do la mayoría de los juegos para la Mega Drive/Genesis y
computador IBM 650. Los lenguajes ensambladores eli- el Super Nintendo Entertainment System.[cita requerida] Se-
minaron mucha de la propensión a errores y del consumo gún algunos insiders de la industria, el lenguaje ensam-
de tiempo de la programación de los lenguajes de prime- blador era el mejor lenguaje de programación a usar para
ra generación, que se necesitaba con los primeros compu-
8 5 USO DEL LENGUAJE ENSAMBLADOR
obtener el mejor desempeño del Sega Saturn, una con- bibliotecas asociadas con un lenguaje de alto nivel;
sola para la cual era notoriamente desafiante desarrollar ésta es quizás la situación más común. Son progra-
y programar juegos.[8] El popular juego de arcade NBA mas empotrados que solo almacenan una pequeña
Jam (1993) es otro ejemplo. El ensamblador ha sido por cantidad de memoria y el dispositivo está dirigido
largo trecho, el lenguaje de desarrollo primario en los para hacer tareas para un simple propósito. Ejem-
computadores hogareños Commodore 64, Atari ST, así plos consisten en teléfonos, sistemas de combustible
como el ZX Spectrum. Esto fue así en gran parte porque e ignición para automóviles, sistemas de control del
los dialectos del BASIC en estos sistemas ofrecieron in- aire acondicionado, sistemas de seguridad, y senso-
suficiente velocidad de ejecución, así como insuficientes res
características para aprovechar completamente el hard-
ware disponible. Algunos sistemas, más notablemente el • Interactuando directamente con el hardware, por
Amiga, incluso tienen IDEs con características de depu- ejemplo en controladores (drivers) de dispositivo y
ración y macros altamente avanzados, tales como el free- manejadores de interrupción
ware ASM-One assembler, comparable a las del Microsoft • Usando instrucciones específicas del procesador no
Visual Studio (el ASM-Uno precede al Microsoft Visual explotadas o disponibles por el compilador. Un
Studio). ejemplo común es la instrucción de rotación bitwise
El ensamblador para el VIC-20 fue escrito por Don en el núcleo de muchos algoritmos de cifrado
French y publicado por French Silk. Con 1639 bytes
• Creando funciones vectorizadas para programas en
de longitud, su autor cree que es el más pequeño en-
lenguajes de alto nivel como C. En el lenguaje de
samblador simbólico jamás escrito. El ensamblador so-
alto nivel esto es a veces ayudado por funciones in-
portaba el direccionamiento simbólico usual y la de-
trínsecas del compilador que mapean directamente
finición de cadenas de caracteres o cadenas hexade-
a los mnemónicos del SIMD, pero sin embargo re-
cimales. También permitía expresiones de direcciones
sulta en una conversión de ensamblador de uno a uno
que podían combinarse con las operaciones de adición,
para un procesador de vector asociado
sustracción, multiplicación, división, AND lógico, OR ló-
gico, y exponenciación.[9] • Es requerida la optimización extrema, ej, en un
bucle interno en un algoritmo intensivo en el uso
del procesador. Los programadores de juegos to-
5.2 Uso actual man ventaja de las habilidades de las característi-
cas del hardware en los sistemas, permitiendo a los
Siempre ha habido debates sobre la utilidad y el desem-
juegos correr más rápidamente. También las gran-
peño del lenguaje ensamblador relativo a lenguajes de
des simulaciones científicas requieren algoritmos al-
alto nivel. El lenguaje ensamblador tiene nichos espe-
tamente optimizados, ej, álgebra lineal con BLAS
cíficos donde es importante (ver abajo). Pero, en gene-
o la transformada de coseno discreta (ej, la versión
ral, los modernos compiladores de optimización para tra-
SIMD en ensamblador del x264,[15] (una biblioteca
ducir lenguajes de alto nivel en código que puede co-
para codificar streams de video)
rrer tan rápidamente como el lenguaje ensamblador es-
crito a mano, a pesar de los contraejemplos que pue- • Un sistema con severas limitaciones de recursos (ej,
den ser encontrados.[10][11][12] La complejidad de los pro- un sistema empotrado) debe ser codificado a mano
cesadores modernos y del subsistema de memoria ha- para maximizar el uso de los limitados recursos; pe-
ce la optimización efectiva cada vez más difícil para ro esto está llegando a ser menos común a medida
los compiladores, así como para los programadores en que el precio del procesador decrece y el desempeño
ensamblador.[13][14] Adicionalmente, y para la consterna- mejora
ción de los amantes de la eficiencia, el desempeño cada
vez mayor del procesador ha significado que la mayoría • No existe ningún lenguaje de alto nivel, en un pro-
de los CPU estén desocupados la mayor parte del tiempo, cesador nuevo o especializado, por ejemplo
con retardos causados por embotellamientos predecibles • Escribiendo programas de tiempo real que necesi-
tales como operaciones de entrada/salida y paginación de tan sincronización y respuestas precisas, tales como
memoria. Esto ha hecho que la velocidad de ejecución sistemas de navegación de vuelo, y equipo médico.
cruda del código no sea un problema para muchos pro- Por ejemplo, en un sistema fly-by-wire (vuelo por
gramadores. mandos eléctricos), la telemetría debe ser interpre-
Hay algunas situaciones en las cuales los profesionales pu- tada y hay que actuar dentro de limitaciones estric-
dieran elegir utilizar el lenguaje ensamblador. Por ejem- tas de tiempo. Tales sistemas deben eliminar fuentes
plo cuando: de retrasos impredecibles, que pueden ser creados
por (algunos) lenguajes interpretados, recolección
• Es requerido un ejecutable binario independiente de basura automática, operaciones de paginación, o
(stand-alone), es decir uno que deba ejecutarse sin multitarea preventiva. Sin embargo, algunos lengua-
recursos a componentes de tiempo de ejecución o a jes de alto nivel incorporan componentes de tiempo
5.3 Aplicaciones típicas 9
de ejecución e interfaces de sistema operativo que estudiar un solo lenguaje ensamblador es suficiente pa-
pueden introducir tales retrasos. Elegir el ensambla- ra aprender: i) los conceptos básicos; ii) reconocer situa-
dor o lenguajes de bajo nivel para tales sistemas da a ciones donde el uso de lenguaje ensamblador puede ser
los programadores mayor visibilidad y control sobre apropiado; y iii) ver cómo el código ejecutable eficiente
el proceso de los detalles puede ser creado por los lenguajes de alto nivel[17]
• Es requerido control total sobre el ambiente, en si-
tuaciones de seguridad extremadamente alta donde
nada puede darse por sentado. 5.3 Aplicaciones típicas
• Se escriben virus de computadora, bootloaders, El lenguaje ensamblador hard-coded es típicamente usa-
ciertos controladores/manejadores de dispositivo, u do en el ROM de arranque del sistema (BIOS en los sis-
otros elementos muy cerca del hardware o al sistema temas compatible IBM PC). Este código de bajo nivel es
operativo de bajo nivel usado, entre otras cosas, para inicializar y probar el hard-
ware del sistema antes de cargar el sistema operativo, y
• Se escriben simuladores del conjunto de instruccio-
está almacenado en el ROM. Una vez que ha tomado lu-
nes para monitoreo, trazado y depuración de errores
gar un cierto nivel de inicialización del hardware, la eje-
donde la sobrecarga adicional es mantenida al míni-
cución se transfiere a otro código, típicamente escrito en
mo
lenguajes de alto nivel; pero el código corriendo inmedia-
• Se hace ingeniería inversa en binarios existentes que tamente después de que es aplicada la energía usualmente
pueden o no haber sido escritos originalmente en está escrito en lenguaje ensamblador. Lo mismo es cierto
un lenguaje de alto nivel, por ejemplo al crackear para los boot loaders.
la protección anticopia del software propietario. Muchos compiladores traducen lenguajes de alto nivel a
• Se hace ingeniería inversa y modificación de video lenguaje ensamblador primero, antes de la compilación
juegos (también denominado ROM hacking), que completa, permitiendo que el código en ensamblador sea
es posible por medio de varios métodos. El más am- visto para propósitos de depuración y optimización. Len-
pliamente implementado es alterando el código del guajes de relativo bajo nivel, como C, con frecuencia pro-
programa a nivel de lenguaje ensamblador veen sintaxis especial para empotrar lenguaje ensambla-
dor en cada plataforma de hardware. El código portable
• Se escribe código automodificable, algo para lo que del sistema entonces puede usar estos componentes espe-
el lenguaje ensamblador se presta bien cíficos a un procesador a través de una interface uniforme.
• Se escriben juegos y otros softwares para El lenguaje ensamblador también es valioso en ingeniería
calculadoras gráficas[16] inversa, puesto que muchos programas solamente son dis-
tribuidos en una forma de código de máquina. El código
• Se escribe software compilador que genera código de máquina es usualmente fácil de trasladar hacia lengua-
ensamblador, y por lo tanto los desarrolladores de- je ensamblador para luego ser cuidadosamente examina-
ben ser programadores de lenguaje ensamblador do en esta forma, pero es muy difícil de trasladar hacia
• Se escriben algoritmos criptográficos que siempre un lenguaje de alto nivel. Herramientas como Interactive
deben tomar estrictamente el mismo tiempo para Disassembler, hacen uso extenso del desensamblador pa-
ejecutar, previniendo ataques de tiempo ra tales propósitos.
Un nicho que hace uso del lenguaje ensamblador es el
Sin embargo, el lenguaje ensamblador es todavía en- demoscene. Ciertas competiciones requieren a los con-
señado en la mayoría de los programas de ciencias de cursantes restringir sus creaciones a un muy pequeño ta-
la computación e ingeniería electrónica. Aunque hoy en maño (ej, 256 bytes, 1 KB, 4 KB ó 64 KB), y el lenguaje
día, pocos programadores trabajan regularmente con el ensamblador es el lenguaje de preferencia para alcanzar
lenguaje ensamblador como una herramienta, los con- este objetivo.[18] Cuando los recursos son una preocupa-
ceptos fundamentales continúan siendo muy importan- ción, es una necesidad la codificación en ensamblador,
tes. Tales tópicos fundamentales, como aritmética bina- especialmente en sistemas constreñidos por el procesa-
ria, asignación de memoria, procesamiento del stack, co- miento del CPU, como los primeros modelos del Amiga,
dificación de conjunto de caracteres, procesamiento de y el Commodore 64. El código optimizado en ensambla-
interrupciones, y diseño de compiladores, serían duros de dor es escrito “a mano” por los programadores en un in-
estudiar en detalle sin la comprensión de cómo el compu- tento de minimizar el número de ciclos de CPU usados.
tador opera a nivel del hardware. Puesto que el compor- Las limitaciones del CPU son tan grandes que cada ciclo
tamiento del computador es fundamentalmente definido cuenta. Usar tales métodos ha habilitado, a sistemas co-
por su conjunto de instrucciones, la manera lógica de mo el Commodore 64, para producir gráficos en 3D en
aprender tales conceptos es estudiar un lenguaje ensam- tiempo real con efectos avanzados, una hazaña que puede
blador. La mayoría de los computadores modernos tie- ser considerada improbable o incluso imposible para un
nen un conjunto de instrucciones similares. Por lo tanto, sistema con un procesador de 0.99 MHz.[cita requerida]
10 7 EJEMPLOS DE LENGUAJE ENSAMBLADOR
8.2 Imágenes
• Archivo:Codigo_de_maquina.png Fuente: https://upload.wikimedia.org/wikipedia/commons/f/f3/Codigo_de_maquina.png Licencia:
Public domain Colaboradores: Trabajo propio Artista original: German
• Archivo:Wikibooks-logo.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/f/fa/Wikibooks-logo.svg Licencia: CC BY-SA
3.0 Colaboradores: Trabajo propio Artista original: User:Bastique, User:Ramac et al.