Está en la página 1de 12

Prctica 2 Entorno de programacin

1. Proceso de ensamblaje 2. Visual Studio .NET

1. Proceso de ensamblaje
El proceso de ensamblado tiene el siguiente esquema: Listado

Editor

fuente 1 fuente 2 fuente 3

Ensamblador

obj 1 obj 2 obj 3

Linker

1.1. Ensamblador
A partir de los fuentes obtenidos de un editor, los fuentes se envan al Ensamblador el cual, traduce los nemotcnicos del lenguaje ensamblador al cdigo objeto de la maquina. Y crea un fichero especial de listado de variables y procedimientos. Por ltimo el Linker toma todos los ficheros objeto y con la informacin sobre las direcciones de memoria para las variables y procedimientos que contiene el fichero Listado, crea el fichero ejecutable final. Normalmente en el proceso de ensamblado bastan con 2 pasos para determinar todas las direcciones, por ejemplo: Jmp etiq etiq: En este caso, cuando el ensamblador no puede determinar la direccin de etiq, ya que sta est definida ms adelante, con lo que debe dejar un espacio y dar una segunda pasada para determinar exactamente el direccin de memoria a la que debe saltar. Por lo tanto, en el 1er paso se utiliza una variable denominada contador de posicin ($). A medida que se analiza el programa, se va incrementando dicha variable en funcin de los bytes que necesita cada sentencia. Por ejemplo: $ .CODE comi: mov ax, @data mov ds, ax mov cx, cont (3 bytes) (2 bytes) (5 bytes)
1

0 3 5

Prctica 1: Introduccin a la programacin en ensamblador

repetir: dec cx

(1 byte)

9 10

Para cada segmento se inicializa el contador de posicin. Ejemplo $ .DATA NUM db -29 VECTOR db 100 DUP ? CONT dw 5 0 1 101 103

Para cada smbolo (variable, constante, etiqueta), se determina su $, su tipo, su nombre de segmento. Con esta informacin, ensamblador construye la TABLA DE SIMBOLOS en esta primera pasada. Luego slo hay que buscar en esa tabla para determinar la direccin de cada etiqueta, constante o variable. El 2 paso comienza cuando se detecta END. Ayudado por las directivas y por los nemotcnicos de las instrucciones se comienza a general el cdigo mquina. Ejemplo: MOV CX, CONT 1 comprobar si el tipo de fuente y destino coinciden 2 comprobar si CONT est en el segmento de datos 3 sustituir CONT por su desplazamiento, que en este caso es 101. No siempre es tan simple: - Pueden existir expresiones aritmticas (que se calculan en este segundo paso). Ejemplo: VAR1 EQU VAR2 + 10

En principio el ensamblador usa valores por defecto. Pero en todo caso, si 2 pasadas no fueran suficientes da un Phase error, Puede indicarle al ensamblador que de ms pasadas. - Otra dificultad aparece con las llamas instrucciones relocalizables, por ejemplo: JMP ETIQ Con ETIQ en otro segmento. Estos valores son se sabe pues no tienen que ver el contador $ (que equivale a un desplazamiento) sino que hay que tener en cuenta es segmento en el que est. Por lo tanto no se conocer el valor correcto hasta que el programa sea colocado en memoria. Para ello los ejecutables .EXE disponen de una cabecera con informacin de relocalizacin donde se indican las instrucciones relocalizables, y poder completar el cdigo una vez situado el programa en memoria.

1.2. Linker
El problema de la relozalizacin: suponer un procesador con memoria lineal. El ensamblador comienza siempre en 0, pero al cargar el programa en memoria no estar en la cero. En el 80x86, es fcil ya que lo nico que hay que hacer es colocar el valor segmento correcto, y seguir los desplazamientos indicados de $. El problema de las llamadas externas:

Departamento de Arquitectura y Tecnologa de Computadores: Universidad de Sevilla

CALL proc MOV AX, SEGMENT JMP far ETIQ En todos estos casos se hacen referencias a otros mdulos. El ensamblador trata cada modulo por separado y el linker soluciona estos problemas. El linker une todos los .obj de forma lineal, asumiendo un solo espacio de direcciones. Aade la cabecera de relocalizacin (en los ejecutable .exe).

2. Visual Studio .NET


La siguiente figura muestra un esquema simplificado de los principales elementos (programas y ficheros) que se manejan en el desarrollo de una aplicacin, en este caso usando lenguaje C:

Son necesarias una serie de operaciones para crear un programa ejecutable que funcione correctamente a partir de uno o varios ficheros fuente: Editar los ficheros fuente con un programa editor. Compilarlos. Enlazarlos con el linker para conseguir el fichero ejecutable. El ejecutable debe probarse con un programa depurador. Si encontramos errores repetiremos el ciclo anterior. Al conjunto de programas que realizan estas o cualquier otra operacin destinada a generar y probar programas se le llama entorno de desarrollo. Tras cada operacin se generan ficheros temporales para comunicar resultados al programa que ejecuta la siguiente operacin, y mensajes para informar al programador del estado del proceso. Necesitamos al menos 4 programas distintos, cada uno de ellos con sus propios parmetros, ficheros de entrada y salida, y mensajes de error o informacin. Para facilitar el manejo de estos programas vamos a utilizar un entorno de desarrollo integrado (IDE: Integrated Development Environment). Un IDE no es ms que un programa que integra el software necesario para el proceso de desarrollo. Como mnimo integra funciones del editor, compilador, linker, depurador y manejador de proyectos (project management). Un proyecto es un fichero o ficheros que contiene la

Prctica 1: Introduccin a la programacin en ensamblador

informacin necesaria para generar un programa: los ficheros fuente que hay que compilar, las opciones de compilacin/enlace, ficheros de salida, listado, etc.

2.1. El entorno de desarrollo Visual Studio .Net.


Este entorno de desarrollo permite utilizar distintos lenguajes de programacin para generar un programa. En TPBN usaremos solamente las caractersticas para programar en lenguaje C/C++ y ensamblador. Es lo que se conoce como Visual C++ .Net (Visual C++ VC++). Utilizaremos VC++ para crear y analizar programas que nos permitan conocer cmo interaccionan procesador y compilador. Crear un proyecto. Empezaremos creando un proyecto y el programa C que vamos a analizar. Con Visual C++ hay que seguir los siguientes pasos: Ejecutar Visual Studio .Net. Aparecer la ventana principal del programa, con este aspecto:

Fig. 2. Pantalla principal de Visual C++. Puede haber pequeas variaciones en el aspecto Debido al aadido o supresin de paneles durante la ltima sesin con el IDE. Se recomienda cerrar los paneles y ventanas que no se vayan a usar.

Crear un proyecto. Proyecto). Pulsar Ctrl-Mays-N (o seleccionar en el men principal Archivo Nuevo Aparece la ventana que permite seleccionar el tipo de fichero o proyecto que se quiere crear:

Departamento de Arquitectura y Tecnologa de Computadores: Universidad de Sevilla

La siguiente ventana es la del asistente para aplicaciones, donde hay que activar la opcin de Proyecto vaco y el tipo de aplicacin: aplicacin de consola.

Fig. 4. Configuracin de la aplicacin.

Crear un fichero .c con el programa principal:

Fig. 5.

Aparecer la ventana Agregar nuevo Elemento, donde se introduce el nombre del archivo fuente de nuestro programa: Principal.c. Esto crea el fichero Principal.c en disco y lo abre en la ventana de edicin. ES MUY IMPORTANTE ASEGURARSE QUE LA EXTENSIN DE LOS FICHEROS C ES .c Y NO .cpp .C. Escribir el cdigo C.

Compilar y depurar el proyecto. El programa se compila pulsando la tecla F7 (o seleccionando Generar Generar Solucin). La depuracin de un programa se suele hacer colocando puntos de interrupcin en las lneas de cdigo que interese. Para activar un punto de interrupcin (breakpoint), hay que pinchar con el ratn en el inicio de la lnea del cdigo fuente donde se quiere parar y pulsar F9 (o pulsar

Prctica 1: Introduccin a la programacin en ensamblador

RATON_DERECHA ventana de edicin.

Insertar/Quitar punto de interrupcin). El punto aparecer marcada en la

Las teclas ms tiles para usar el depurador (debugger) son1: Ejecutar depurador (F5), terminar depuracin (Mayscula + F5) Mostrar ventana de desensamblado (Alt + 8 Depurar Mostrar ventana de registros (Alt + 5) Mostrar ventana de memoria (Alt + 4) Ejecutar paso a paso: Pinchar ventana de desensamblado y pulsar F11 Todas las ventanas del depurador se pueden organizar dentro de la ventana principal de la forma que resulte ms cmoda. La siguiente figura muestra la ventana de desensamblado, que permite ver las direcciones donde estn almacenados el cdigo y la variable de nuestro programa. La ventana de registros tambin permite ver el valor del puntero de pila, ESP, que seala el final de la pila. Ventanas Desensamblador)

Fig. 6. Ventanas de depuracin.

Como se ve, la direccin que seala el puntero de pila es menor que las direcciones donde se almacena cdigo o datos, lo que nos indica que la pila est colocada en las posiciones ms bajas de la memoria.

2.2. Cmo funcionan los depuradores.


Un depurador es un programa capaz de parar la ejecucin de otro cuando se dan determinadas circunstancias: Se ha llegado a un punto determinado del cdigo (punto de parada o breakpoint de cdigo). Se ha ejecutado una sola instruccin (ejecucin paso a paso). Se accede a datos o se intenta ejecutar cdigo de zonas de memoria fuera de las asignadas al programa (deteccin de accesos ilegales a memoria). Se intenta acceder a una variable determinada (breakpoint de datos). etc. Cuando ocurre algo de esto, se produce una excepcin, es decir, el procesador salva su estado (valor de los registros internos) y salta a una funcin del sistema operativo que debe manejar la

Departamento de Arquitectura y Tecnologa de Computadores: Universidad de Sevilla

excepcin. El proceso es muy similar al de una interrupcin hardware. La funcin del sistema operativo normalmente pasa el control al depurador, que informa al programador. Las circunstancias concretas tratables por un depurador dependen fundamentalmente del hardware de depuracin del procesador. Hay grandes diferencias entre distintos procesadores. Algunos no disponen de ninguna facilidad, por lo que lo nico que pueden hacer los depuradores son breackpoints de cdigo y ejecucin paso a paso4. Los procesadores con arquitectura IA32 (Pentium y sucesores) disponen de un hardware muy completo para depuracin y anlisis de prestaciones. Cuatro registros de depuracin, DR0 a DR3 (Debug Registers), permiten especificar las direcciones a analizar, y con dos registros de control, DR6 y DR5, se indican cules son las condiciones que provocan la excepcin de depuracin: breackpoints de cdigo o datos, ejecucin paso a paso y muchas ms. La variedad de condiciones que es capaz de detectar un procesador IA32 es realmente extensa, por lo que el hardware de depuracin es complicado de manejar. De hecho, muchos depuradores no utilizan todas las condiciones. Una vez parada la ejecucin del programa que se est depurando, la informacin a mostrar depende fundamentalmente del sofware del depurador. En el caso de VC++ la tenemos agrupada en ventanas: Ventana de cdigo. El cdigo se puede mostrar en varios formatos: Desensamblado. Es el ms bsico: siempre se puede utilizar, tenga o no informacin de depuracin el ejecutable. Desensamblado + fuente. Muestra el cdigo ensamblador que corresponde a cada sentencia del cdigo fuente. Para usarlo es necesario que el depurador disponga del fichero fuente y que el fichero ejecutable tenga informacin de depuracin. Slo fuente.

Fig. 9. Ventana de cdigo con programa desensamblado y fuente.

Ventanas de memoria. Muestran el contenido de cualquier zona de la memoria virtual del programa en formato hexadecimal de 8 bits (byte), 16 (Short Hex) o 32 (Long hex). El programador puede modificar el contenido de la memoria que aparece en la ventana.

Fig. 10

Prctica 1: Introduccin a la programacin en ensamblador

Ventana de registros. Contiene los registros que se pueden modificar desde una aplicacin de usuario5.

Fig. 11. Ventana con los registros enteros y los indicadores (flags).

Ventanas de inspeccin (watch). Permite seleccionar elementos puntuales para ver y modificar su contenido: registros, posiciones de memoria, variables, etc.

Fig. 12

Ventana de variables. Permite ver y modificar el valor de las variables locales. Ventana de pila de llamadas. Muestra el rbol de llamadas de la instruccin de cdigo donde nos hemos detenido por ltima vez.

2.3. Puntos a tener en cuenta.


Las ventanas de la pantalla principal (Fig. 2). Las funciones de las ventanas ms importantes son: Ventanas de edicin: Sirven para editar los ficheros con cdigo fuente. Ventana de proyectos. Permite manejar y organizar los ficheros fuente del proyecto. Ventana de mensajes: es donde aparecen los mensajes de error o estado que se generan al ejecutar un elemento del entorno de desarrollo: compilador, linker, etc. Tipos de proyectos (Fig. 3). Cuando seleccionamos el tipo de proyecto estamos escogiendo unas opciones por defecto para el proceso de desarrollo: las opciones de compilacin, las libreras y ficheros objeto con los que se enlazar, opciones de depuracin, etc. Al seleccionar una aplicacin de tipo consola le decimos a VC++ que active las opciones de compilacin necesarias para que nuestra aplicacin pueda usar las funciones de manejo de consola estndar de C: printf, getc, putc, etc. Extensiones de los archivos fuente (Fig. 5). La extensin del nombre de un fichero fuente determina las opciones por defecto de compilacin/linkado. Algunas extensiones, como .c .cpp, ya tienen preasignadas estas opciones. Esto quiere decir que si llamamos a un programa Principal.c, se compilar de forma ligeramente distinta que si lo llamamos Principal.cpp. La mayor diferencia es que un fichero .c slo puede usar las caractersticas de C, y no de C++. En principio, si un programa slo usa C, podra tener cualquiera de las dos extensiones. Sin embargo, internamente se compilar de forma distinta, y algunas caractersticas del cdigo generado tambin sern distintas. Por tanto, para evitar confusiones a la hora de analizar el cdigo generado por el compilador, hay que procurar usar la extensin .c en todos los programas de prcticas.

Departamento de Arquitectura y Tecnologa de Computadores: Universidad de Sevilla

2.4. Compilacin externa en Visual C++.


Algunos entornos de desarrollo pueden compilar ficheros de un proyecto con compiladores externos. El mecanismo concreto para hacerlo depender del entorno de desarrollo. Supongamos, por ejemplo, que inicialmente todos los ficheros fuente del proyecto son programas C que se compilan con el compilador interno de Visual Studio. El proyecto tendra la siguiente estructura:

Cuando genera el ejecutable, Visual Studio procesa automticamente los ficheros fuente que componen el proyecto. Para los que tengan extensin conocida por Visual Studio (.h, .c, .cpp, ...), el IDE ejecuta el compilador interno que tiene asociada la extensin3. Una vez obtenido todos los ficheros objeto, el IDE lanza el linker interno para generar el ejecutable. Para las extensiones conocidas por Visual Studio el IDE sabe qu compilador utilizar, cmo usarlo (con qu opciones) y cul es el resultado de la compilacin (el fichero objeto). Para compilar algn fichero fuente con un compilador externo a Visual Studio hay que indicar al IDE cmo tiene que tratarlo. Esto implica que: El fichero fuente debe tener una extensin no conocida para el IDE. En caso contrario, usar la compilacin por defecto para esa extensin. Hay que indicarle al IDE que debe hacer una compilacin a medida (Custom Build) para ese fichero. Vamos a modificar el proyecto, para que uno de los ficheros se compile usando un ensamblador externo. La estructura del proyecto quedara:

Prctica 1: Introduccin a la programacin en ensamblador

Para ello se tendra que borrar el fichero Combina3.c y crear uno nuevo llamado Combina3.asm. Como el IDE no sabe cmo manejarlos, no hace ninguna operacin sobre ficheros .asm a menos se lo indiquemos explcitamente activando la compilacin personalizada (Custom Build). La forma de hacerlo es: Seleccionamos el fichero en la ventana Explorador de soluciones y pulsamos el botn de la derecha del ratn. Seleccionar Propiedades en el men que aparezca. El IDE mostrar la ventana de propiedades asociadas al fichero. Seleccionando la entrada Paso de generacin personalizada (Fig. 3) podremos ajustar los tres campos necesarios para integrar el compilador externo:

Lnea de comandos: Es la lnea de comandos que ejecutar el IDE para procesar el fichero. Descripcin: Es el mensaje que mostrar el IDE cuando procese el fichero fuente. Resultado: Es el resultado de la compilacin externa. Le indica al linker (vinculador o enlazador) interno el fichero que tiene que usar.

10

Departamento de Arquitectura y Tecnologa de Computadores: Universidad de Sevilla

Fig. 3. Ventana Paso de generacin personalizada.

En nuestro ejemplo, la compilacin de combina3.asm tendr los siguientes parmetros: Lnea de comandos: \masm32\bin\ml.exe /Zi /Zd /Cp /c /coff /Gd "$(InputPath)". Hay que asegurarse que el ensamblador o compilador externo est previamente instalado y que tiene el path y las opciones correctas en las lneas de comandos. Descripcin: Ensamblando "$(InputPath)". El IDE sustituye la cadena $(InputPath) por el nombre completo del fichero de entrada, incluyendo su path. Resultado: "$(InputName).obj". El IDE sustituye la cadena $(InputName) por el nombre completo del fichero, incluyendo path, pero excluyendo la extensin. Las distintas cadenas de sustitucin que pueden utilizarse en los campos de la ventana Paso de generacin personalizada se insertan con el botn Macro de la ventana que aparece cuando se pulsa . Ya estara integrado el fichero ensamblador en el proceso de construccin del ejecutable. El IDE lanza automticamente el ensamblador cada vez que se necesite, mostrando los mensajes de error o estado en la ventana de Resultados:

11

Prctica 1: Introduccin a la programacin en ensamblador

3. Primer programa en Ensamblador


El siguiente cdigo corresponde a un programa escrito en ensamblador que suma dos vectores de enteros almacenando el resultado en un tercero. .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc .data vect1 DD 10 dup (1,2,3,4,5,6,7,8,9,10) vect2 DD 10 dup (10,9,8,7,6,5,4,3,2,1) vectres DD 10 DUP (?) .code start: mov ecx, 10 xor edx,edx inibucle: mov eax, vect1[edx] add eax ,vect2[edx] mov vectres[edx] , eax add edx,4 loop inibucle call ExitProcess end start

12