Vous êtes sur la page 1sur 16

1 FUNDAMENTOS DEL LENGUAJE ENSAMBLADOR

Objetivos
1. Enterarse sobre sistemas actuales con funcionalidades soportadas a bajo nivel
2. Saber sobre la evolución de los microprocesadores Intel x86 y AMD
3. Conocer diferentes plataformas de programación a bajo nivel
4. Diseñar e implementar programas simples en ensamblador

El lenguaje ensamblador, es un lenguaje de programación de bajo nivel para las computadoras,


microprocesadores, microcontroladores y otros circuitos integrados programables. Implementa una
representación simbólica de los códigos de máquina binarios y otras constantes necesarias para
programar una arquitectura dada CPU y constituye la representación más directa del código máquina
específica para cada arquitectura legible por un programador.

Lenguaje Ensamblador es la primera abstracción del Lenguaje de Máquina, consistente en asociar a


los códigos de operación (opcodes) palabras clave que faciliten su uso por parte del programador.

Ejemplo opcodes en ensamblador

Existe un distinto Lenguaje de Máquina para cada CPU. Por ejemplo, podemos mencionar tres
lenguajes completamente diferentes, que sin embargo vienen de la aplicación de los conceptos
anteriores:

1. Lenguaje Ensamblador de la familia Intel 80x86


2. Lenguaje Ensamblador de la familia Motorola 68000
3. Lenguaje Ensamblador del procesador POWER, usado en las IBM RS/6000.

Existen muchos ensambladores como por ejemplo: Microsoft MASM el cual se ejecuta en MS-
Windows. Hay otros ensambladores muy buenos para las computadoras basadas en Intel, incluyendo
TASM (Turbo Assembler), NASM (Netwide Assembler), y el ensamblador de GNU.
1.2 Organización de la computadora

1.2.1 El Microprocesador

El microprocesador es un circuito integrado que contiene algunos o todos los elementos necesarios
para conformar una (o más) “unidad central de procesamiento” UCP, también conocido como CPU
(por sus siglas en inglés: Central Process Unit). En la actualidad este componente electrónico está
compuesto por millones de transistores, integrados en una misma placa de silicio.

Está conformado por los siguientes elementos: Memoria, Unidad Aritmetica Logica (ALU), Puertos de
Entrada y Salida (Buses), La Unidad de Control (UC) y un reloj que sincroniza su funcionamiento.

1.2.2 Buses
Buses de comunicación en un circuito impreso. En Arquitectura de computadoras, el bus es un sistema
digital que transfiere datos entre los componentes de una computadora entre computadores. Están
formado por cables o pistas en un circuito impreso, dispositivos como resistencias y condensadores
además de circuitos integrados.

La mayoría de los buses están basados en conductores metálicos por los cuales se trasmiten señales
eléctricas que son enviadas y recibidas con la ayuda de integrados que poseen una interfaz del bus
dado y se encargan de manejar las señales y entregarlas como datos útiles.
1.2.3 Registros

Los registros del procesador se emplean para controlar instrucciones en ejecución, manejar
direccionamiento de memoria y proporcionar capacidad aritmética. Los registros son espacios físicos
dentro del microprocesador con capacidad de 4 bits hasta 64 bits dependiendo del microprocesador
que se emplee. Los bits, por conveniencia, se numeran de derecha a izquierda (15,14,13…. 3,2,1,0),
los registros están divididos en seis grupos los cuales tienen un fin específico. Los registros se dividen
en:

• Registros de segmento

• Registros de apuntadores de instrucciones

• Registros apuntadores

• Registros de propósitos generales

• Registro índice

• Registro de bandera.

1.2.4 Modos De Direccionamiento

Esta operación debe realizarse sobre algunos datos almacenados en registros de computadora o en
palabras de memoria. La manera en que eligen los operandos durante la ejecución del programa
depende del modo de direccionamiento de la instrucción. El modo de direccionamiento especifica una
regla para interpretar o modificar el campo de dirección de la instrucción antes de que se haga la
referencia real al operando.

Las computadoras utilizan técnicas de modo de direccionamiento para acomodar una o las dos
siguientes consideraciones:

1. Proporcionar al usuario versatilidad de programación al ofrecer facilidades como apuntadores


a memoria, contadores para control de ciclo, indexación de datos y reubicación de datos.

2. Reducir la cantidad de bits en el campo de direccionamiento de la instrucción.

La unidad de control de una computadora está diseñada para recorrer un ciclo de instrucciones que
se divide en tres fases principales:

1. Búsqueda de la instrucción de la memoria.


2. Decodificar la instrucción.
3. Ejecutar la instrucción.
Hay un registro en la computadora llamado contador de programa o PC, que lleva un registro de
las instrucciones del programa almacenado en la memoria. Pc contiene la dirección de la siguiente
instrucción que se va a ejecutar y se incrementa cada vez que se recupera una instrucción de la
memoria.

Aunque la mayoría de los modos de direccionamiento modifican el campo de dirección de la


instrucción, hay dos modos que no necesitan el campo de dirección. Son los modos implícito e
inmediato.

 Modo Implícito.
 Modo Inmediato.
 Modo De Registro.
 Modo Indirecto Por Registro.
 Modo De Direccionamiento Directo.
 Modo De Direccionamiento Indirecto.
 Modo De Direccionamiento Indexado.
 Modo De Direccionamiento De Registro Base.

1.3 Interrupciones

Una interrupción es una operación que suspende la ejecución de un programa de modo que el sistema
pueda realizar una acción especial. La rutina de interrupción ejecuta y por lo regular regresa el control
al procedimiento que fue interrumpido, el cual entonces reasume su ejecución.

1.3.1 Hardware
Las interrupciones hardware, ocurren cuando un dispositivo necesita atención del procesador y
genera una señal eléctrica en la línea IRQ que tiene asignada. Esta señal es recogida y procesada
por el controlador de excepciones PIC antes de ser enviada al procesador, lo que puede realizarse de
dos formas, según el tipo de interrupción sea enmascarable o no enmascarable.

Cuando se habla de una interrupción significa que, bajo control del software, el procesador puede
aceptar o ignorar (enmascarar) la señal de interrupción. Para ello se envía una señal a la patilla
INTR, y el procesador la atiende o la ignora en función del contenido de un bit (IF) en un registro
(FLAGS) que puede estar habilitado o deshabilitado.

1.3.2 Software
Los procesadores Intel de la gama x86 y compatibles, disponen de una instrucción INT que permite
generar por software cualquiera de los 256 tipos de interrupción. El proceso seguido es exactamente
el mismo que si se recibe una interrupción hardware en la patilla INTR, salvo que en este caso se
conoce el tipo de interrupción, y no se requiere ningún ciclo INTA.

Este tipo de interrupciones son de prioridad más alta que las de hardware (enmascarables y no
enmascarables), de forma que si se recibe una interrupción hardware mientras que se ejecuta una
software, esta última tiene prioridad.
1.2 Lenguaje máquina y lenguaje ensamblador
1.2.1 Lenguaje máquina

Fue el primer lenguaje utilizado en la programación para las primeras computadoras, pero dejó de
utilizarse por su dificultad y complicación, siendo sustituido por otros lenguajes más fáciles de
aprender y utilizar, y que además reducen la posibilidad de cometer errores.

El código máquina, o lenguaje de máquina, está formado por instrucciones sencillas, que
dependiendo de la estructura del procesador pueden especificar:

 Registros específicos para operaciones aritméticas, direccionamiento o control de funciones.


 Posiciones de memoria específicas (offset).
 Modos de direccionamiento usados para interpretar operando.

Las instrucciones de máquina o instrucciones de la computadora son las que determinan el


funcionamiento de la CPU que las ejecut.

Ventajas del Lenguaje Máquina.

 Posibilidad de cargar (transferir un programa a la memoria) sin necesidad de traducción


posterior, lo que supone una velocidad de ejecución superior a cualquier otro lenguaje de
programación.

Desventajas del Lenguaje Máquina.

 Dificultad y lentitud en la codificación.


 Poca fiabilidad.
 Gran dificultad para verificar y poner a punto los programas.
 Los programas solo son ejecutables en el mismo procesador (CPU).

1.2.2 Lenguaje ensamblador

El lenguaje ensamblador es un tipo de lenguaje de bajo nivel utilizado para escribir programas
informáticos y constituye la representación más directa del código máquina específico para cada
arquitectura de computadoras legible por un programador

Uso: Fue usado principalmente en los inicios del desarrollo de software, cuando aún no se contaba
con los potentes lenguajes de alto nivel.

Muchos dispositivos programables (como los microcontroladores) aun cuentan con el ensamblador
como la única manera de ser manipulados.

Las características más destacadas del lenguaje ensamblador son:

1) Difícil de entender directamente.


2) Poco portable.
3) Los programas son más rápidos y consumen menos recursos.
4) Se tiene un control muy preciso de las tareas que se van a realizar.
5) Se puede controlar el tiempo que tarda en ejecutarse una rutina.
6) Se puede impedir que se interrumpa un programa durante su ejecución.

Su importancia: Es considerado de primera generación a partir de el se derivaron todos los demás


lenguajes hasta llegar al de alto nivel.

Fuente:http://arquitecturadelcomputadorsemestre6.blogspot.mx/2014/10/lenguaje-maquina-y-lenguaje-ensamblador.html

1.3 Lenguaje ensamblador y lenguaje de alto nivel


Lenguaje de programación de alto nivel es un tipo de lenguaje de programación que permite
al programador escribir programas que son más o menos independientes de un tipo particular de
computadora (del hardware). Estos lenguajes son considerados de alto nivel porque son más
parecidos al lenguaje humano y menos al de las máquinas.

La principal ventaja de los lenguajes de alto nivel sobre los de bajo nivel es que son más fáciles de
leer, escribir y mantener por humanos.

Ventajas y desventajas de los lenguajes de programación de alto nivel

Ventajas

 Resultan en un código fuente más fácil de leer, escribir y mantener por los humanos. En
general, permite emplear menos líneas de código en comparación con lenguaje máquina.
 Permiten escribir un código válido ejecutable en distintos tipos de máquinas y sistemas
operativos.
 Emplean paradigmas de programación.

Desventajas

 Son más lentos de ejecutar, siendo el código máquina más eficiente. De todas maneras esto
depende del diseño del compilador para lenguajes de alto nivel: un buen diseño produce más
eficiencia.
 En algunos casos el programa resultante requiere una determinada plataforma para
ejecutarse.

Ejemplos de lenguajes de programación de alto nivel

Los primeros lenguajes de programación de alto nivel fueron diseñados en los 50. Actualmente
existen cientos de lenguajes de este tipo como:

 Ada
 BASIC
 COBOL
 C (algunos lo consideran de nivel medio)
 C++ (algunos lo consideran de nivel medio)
 Delphi
 FORTRAN
 Java
 LISP
 Modula-2
 Perl
 php
 Prolog
 Python
 Visual Basic .NET

1.4 Aplicación de los lenguajes ensamblador


El uso del lenguaje ensamblador no es para la gente común y corriente, sino para profesionistas en
el área de computación que están obligados a conocer este lenguaje, ya que proporciona una serie
de características que no se pueden encontrar en los lenguajes de alto nivel, se centran básicamente
en aplicaciones de tiempo real, control de procesos y de dispositivos electrónicos.

Algunas de estas características son:

 Se puede acceder a cualquier localidad de la memoria RAM sin ninguna restricción.


 Se pueden programar virus, debido a que se tiene un acceso total a casi todo el hardware
de la computadora vía interrupciones de software.
 Se pueden programar drivers de cualquier dispositivo.
 Se puede acceder directamente a los registros internos del CPU.
 Programación de Microcontroladores
 Creación de compiladores

Áreas en las que se aplica:

 Sistemas Embebidos: impresoras, cámaras, autos, juguetes, etc.


 Industria y Manufactura: adquisición datos y control, eg robots.
 Transporte y Aeronáutica: barcos, aviones, sondas espaciales, etc.
 Graficación, Multimedia, Cine y Video Juegos
 Procesamiento de Señales, Voz e Imágenes
El lenguaje ensamblador no es portable porque su diseño es para una familia de procesadores
específica.

1.5 Tipos de ensambladores


Aunque todos los ensambladores realizan básicamente las mismas tareas, podemos clasificarlos de
acuerdo a características.

Así podemos clasificarlos en:

 Ensambladores Cruzados (Cross-Assembler). Se denominan así los ensambladores que


se utilizan en una computadora que posee un procesador diferente al que tendrán las
computadoras donde va a ejecutarse el programa objeto producido. El empleo de este tipo
de traductores permite aprovechar el soporte de medios físicos (discos, impresoras,
pantallas, etc.), y de programación que ofrecen las máquinas potentes para desarrollar
programas que luego los van a ejecutar sistemas muy especializados en determinados tipos
de tareas.

 Ensambladores Residentes. Son aquellos que permanecen en la memoria principal de la


computadora y cargan, para su ejecución, al programa objeto producido. Este tipo de
ensamblador tiene la ventaja de que se puede comprobar inmediatamente el programa sin
necesidad de transportarlo de un lugar a otro, como se hacía en cross-assembler, y sin
necesidad de programas simuladores.

 Macroensambladores. Son ensambladores que permiten el uso de macroinstrucciones


(macros). Debido a su potencia, normalmente son programas robustos que no permanecen
en memoria una vez generado el programa objeto.

 Microensambladores. El programa que indica al intérprete de instrucciones de la UCP


cómo debe actuar se denomina microprograma. El programa que ayuda a realizar esté
microprograma se llama microensamblador. Existen procesadores que permiten la
modificación de sus microprogramas, para lo cual se utilizan microensambladores.

 Ensambladores de una fase. Estos ensambladores leen una línea del programa fuente y
la traducen directamente para producir una instrucción en lenguaje máquina o la ejecuta si
se trata de una pseudoinstrucción. También va construyendo la tabla de símbolos a medida
que van apareciendo las definiciones de variables, etiquetas, etc.

 Ensambladores de dos fases. Los ensambladores de dos fases se denominan así debido
a que realizan la traducción en dos etapas. En la primera fase, leen el programa fuente y
construyen una tabla de símbolos; de esta manera, en la segunda fase, vuelven a leer el
programa fuente y pueden ir traduciendo totalmente, puesto que conocen la totalidad de los
símbolos utilizados y las posiciones que se les ha asignado.
1.6 Estructura de un programa en ensamblador
Un programa en lenguaje ensamblador estará formado por una secuencia de sentencias. Cada
sentencia ocupa una sola línea y tiene la siguiente estructura:

[etiqueta] [operación] [operandos] [;comentarios]

Los cuatro campos de una sentencia son opcionales, si no aparece ninguno de ellos (una línea en
blanco) tendríamos una sentencia vacía.

Las sentencias se dividen en dos tipos:

 Instrucciones: Estas sentencias representan órdenes al procesador y tras el proceso de


compilación generan código ejecutable.
 Directivas: Estas sentencias dirigen el proceso de compilación o construcción del programa
ejecutable. No generan código ejecutable. Normalmente se utilizan para aumentar la
legibilidad del código fuente.

Estructura de un archivo en lenguaje ensamblador

Los archivos de código fuente escritos en lenguaje ensamblador se organizan en líneas. Cada una de
las líneas del archivo puede contener una directiva, una instrucción o ambas cosas a la vez en los
casos en que sea posible.

Todos los archivos fuente tienen que adecuarse a una estructura fija dividida en secciones.

Los diferentes segmentos tienen las siguientes funciones:

 Segmento de datos: Contiene la dirección donde inicia la declaración de variables. Aquí,


escribiremos nuestras variables.
 Segmento de código: Contiene la dirección de inicio donde se encuentran las instrucciones
del programa. Aquí, escribiremos todo el código de nuestro programa
 Segmento de pila: Contiene la dirección donde se encuentra la pila.
 Segmento Extra: Contiene la dirección donde podemos almacenar datos extras.
Como ya hemos comentado con anterioridad el lenguaje Ensamblador no es solo código, sino que
de igual manera hay ciertas cuestiones involucradas como lo son los registros, banderas, etc.

A continuación verás el código que utilicé para crear programa1.exe:

Aquí la descripción de la numeración de la figura anterior:

1. .386 - Describe el modelo de CPU para el cual el código está dirigido; en este caso como
estamos haciendo el programa para x86 se puede utilizar la directiva .386. Como nota
adicional hay que poner atención en el punto inicial el cual es requerido antes de cualquier
directiva.

2. .model flat, stdcall - La directiva .model: En esta directiva se define básicamente el


modelo –o tipo- de memoria utilizado que utilizará el programa que estás desarrollando. Aquí
no hay muchas opciones por lo que solamente tendrás una: flat y stdcall. Stdcall indica el
tipo de convención a utilizar para el paso de parámetros al utilizar funciones. option
casemap :none indica que sea sensitivo a mayúsculas y minúsculas.

3. include – Tal como es utilizado en otros lenguajes, los “includes” tienen el mismo objetivo
en Ensamblador; el cual es “incluir” en el código las librerías a utilizarse. Para el caso de
Ensamblador sobre Windows (Win32) se utiliza principalmente las librerías e “includes”
relacionadas a las dll’s que conocemos son parte del Sistema Operativo, y me refiero a
windows, kernel32 y user32.

4. .data - La directiva .data se utiliza para hacer la declaración de las variables. Se puede decir
que la directiva – .data será el repositorio de las variables inicializadas del programa. Existen
otras directivas como .DATA? la cual tiene la misma función que .DATA, con la única
diferencia que ésta sirve para almacenar datos no-inicializados. De igual manera se tiene la
directiva .CONST que como puede deducirse sirve para almacenar las constantes que se
quieran utilizar en el programa.

5. .code - La directiva .code, como es de suponerse es en donde se escribirá el código del


programa.
.start y end start – Indican el principio y el fin del bloque de código. invoke – Es una
forma se “llamar” a una función. De igual modo se podría utilizar una llamada “CALL”, sin
embargo para evitar cuestiones relacionadas al manejo de errores es mayormente
recomendable el uso de invoke.

Cada vez que generes un nuevo programa podrías utilizar la siguiente pieza de código
como plantilla:

.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

. data
<variables>
.code
start:
<código>
end start

1.8 Procedimiento de Ensamble, Enlace Y Ejecución


Tal como está, el programa es solo un archivo de texto que no puede ejecutarse; primero debe
ensamblarlo y enlazarlo.

1. El paso de ensamble consiste en la traducción del código fuente en código objeto y la


generación de un archivo intermedio .OBJ. El ensamblador también crea un encabezado al
frente del módulo .OBJ generado; parte del encabezado tiene información acerca de
direcciones incompletas.

2. El paso de enlace implica convertir un módulo .OBJ en un módulo de código máquina .EXE
3. El último paso es cargar el programa para su ejecución. Ya que el cargador conoce en dónde
está el programa a punto de ser cargado, puede completar las direcciones indicadas en el
encabezado que estaban incompletas.

1.9 El entorno de programación


Para poder crear un programa se requieren varias herramientas:

 Primero un editor para crear el programa fuente.


 Segundo un compilador que no es más que un programa que "traduce" el programa fuente
a un programa objeto.
 Y tercero un enlazador o linker, que genere el programa ejecutable a partir del programa
objeto.

El editor puede ser cualquier editor de textos que se tenga a la mano, como compilador utilizaremos
el MASM (macro ensamblador de Microsoft) ya que es el más común, y como enlazador utilizaremos
el programa link.

La extensión usada para que MASM reconozca los programas fuente en ensamblador es .ASM; una
vez traducido el programa fuente, el MASM crea un archivo con la extensión .OBJ, este archivo
contiene un "formato intermedio" del programa, llamado así porque aún no es ejecutable pero
tampoco es ya un programa en lenguaje fuente. El enlazador genera, a partir de un archivo .OBJ o
la combinación de varios de estos archivos, un programa executable.

Pueden usar visual studio 2012 o 2015 aunque son algo pesado, es por esta razón que se utilizará el
Visual Masm
Aquí les dejo la página del autor, de donde lo pueden descargar http://www.visualmasm.com/, solo
es necesario bajar el visualmasm.zip los descomprimen e instalan, durante la instalación de sugerirá
en descargar el Masm32 el más reciente e instalarlo en la dirección correcta para que lo reconozca
sin ningún inconveniente

Una vez que tenemos el código asm, tenemos que obtener el obj, este paso se realiza abriendo la
ventana de comandos y escribimos lo siguientes:

C:\masm32\bin\ml /c /Zd /coff hola_mundo.asm

Debe escribirse tal y como aparece en la línea anterior, ya que se tiene el archivo .obj debemos
obtener el ejecutable, el cual lo realizaremos con la siguiente línea

C:\masm32\bin\Link /SUBSYSTEM:CONSOLE hola_mundo.obj

Y por último ejecutamos el hola_mundo.exe, invocándolo desde la ventana de consola

Hola_mundo.asm
.386
.model flat,stdcall
option casemap:none

include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\msvcrt.inc

includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\msvcrt.lib

.data
text1 db "Hola Mundo!", 0Ah, 0 ; 0Ah =\n

.code
start:
invoke crt_printf,ADDR text1
invoke ExitProcess,0
END start

Utilizaremos librerías auxiliares que contienen macros para leer y escribir en pantalla

include c:\masm32\include\msvcrt.inc
includelib c:\masm32\lib\msvcrt.lib
Abrimos la consola

Creamos el .obj y el .exe


Ejemplos del hola mundo en diferentes ensambladores

Fuente: https://es.wikipedia.org/wiki/Anexo:Ejemplos_de_implementaci%C3%B3n_del_%C2%ABHola_mundo%C2%BB

Vous aimerez peut-être aussi