You are on page 1of 7

Tcnicas de programacin en bajo nivel (TPBN)

3 Ingeniera en Informtica. ETSI Informtica.


Universidad de Sevilla. 24/25 de marzo de 2008.

Prctica 2: Programacin estructurada en lenguaje ensamblador.


Ensamblado en lnea.

Los objetivos de la prctica son:


Introduccin al ensamblado en lnea.
Mostrar cmo se puede usar el ensamblado en lnea para estudiar la arquitectura ISA de
un procesador.
Ver como se implementan en lenguaje ensamblador los bloques ms usados en la
programacin estructurada: IF THE%, IF THE% ELSE, WHILE, REPEAT
U%TIL, FOR.

Qu hay que saber antes de entrar en el laboratorio:


Formato general de las instrucciones del IA32.
Instrucciones aritmticas y lgicas.
Instrucciones de salto.
Ensamblado en lnea.

Contenido:
P2.1. Ensamblado en lnea..................................................................................................... 1
P2.2. Bloques de programacin estructurada......................................................................... 3
P2.3. Depuracin en el entorno Visual Studio C++. La ventana de inspeccin. ................... 5
Condiciones de uso: Cundo se pueden utilizar. ................................................................... 5
Qu informacin podemos ver y/o modificar. ....................................................................... 5
Formato de la visualizacin. .................................................................................................. 6
P2.4. Cuestiones. ................................................................................................................... 7

Los lenguajes de alto nivel suelen tener instrucciones que permiten implementar directamente
las construcciones ms comunes en la programacin estructurada. El juego de instrucciones de un
procesador (y, por tanto, el lenguaje ensamblador) no suele implementar directamente estas
construcciones, sino que se tienen que realizar con instrucciones de comparacin y de salto
condicional o incondicional (equivalentes al goto de C). Sin embargo, esto no quiere decir que la
programacin estructurada no se usa en lenguaje ensamblador. No hay que olvidar que todas las
estructuras de cdigo de un lenguaje de alto nivel se traducen a cdigo mquina y, por tanto, tienen
su equivalente en lenguaje ensamblador.

P2.1. Ensamblado en lnea.


El ensamblado en lnea es la forma ms sencilla de utilizar el lenguaje ensamblador. Consiste en
introducir lneas de lenguaje ensamblador directamente en un programa en lenguaje de alto nivel.

1
Fig. 1. Ensamblado en lnea dentro de un programa Visual C.

Prcticamente todos los compiladores de C y C++ que se utilizan hoy en da en procesadores de


32 bits permiten el ensamblado en lnea, aunque la sintaxis y las reglas de utilizacin varan de un
compilador a otro.
La figura 1 muestra un ejemplo de ensamblado en lnea en Visual C++. El bloque en lenguaje
ensamblador comienza con la palabra reservada __asm (dos guiones _ seguidos de asm). La
forma de tratar el bloque en ensamblador puede variar de un compilador a otro. Normalmente
traduce todo el cdigo C a lenguaje ensamblador, introduciendo el bloque __asm en el lugar que le
corresponda, y a continuacin lo ensambla todo.
Como se ve en la figura, el ensamblado en lnea permite usar los smbolos (nombres de
variables, funciones, etc.) definidos en el cdigo C.
El formato general de cada lnea de cdigo en ensamblador para IA32 es:

Etiqueta: ombre_de_Instruccin operando1, operando2 ;Comentario

Los cinco componentes son opcionales.

Etiqueta es un nombre simblico. Utiliza las mismas reglas que los nombres de funcin en
C. El valor de Etiqueta es la direccin virtual donde se almacena el primer byte del cdigo
de operacin de la instruccin.
ombre_de_Instruccin es el nombre de cualquiera de las instrucciones del procesador.
operando1, operando2. Si la instruccin tiene 2 operandos, operando2 es el operando
fuente y operando1 es el operando destino (y tambin fuente en las operaciones aritmtico-
lgicas). Como operandos se pueden usar:
o Constantes numricas.
o Nombres de variables o funciones definidas en el cdigo fuente C: el
ensamblador las sustituye por su direccin.

Otra opcin para usar el lenguaje ensamblador es utilizar un programa ensamblador


independiente del compilador. La parte del cdigo fuente en ensamblador se ensambla por separado
de la parte en lenguaje de alto nivel y despus se unen usando un enlazador (linker). El proceso es
similar al que se usa en la programacin modular con cualquier lenguaje de alto nivel.

2
La gran ventaja del ensamblado en lnea frente al ensamblado independiente es que es mucho
ms fcil de usar, sobre todo si se tiene que mezclar ensamblador con lenguaje de alto nivel.
Entre las desventajas del ensamblado en lnea, tenemos:
No todos los lenguajes y/o compiladores lo permiten. El C bsico es lo suficientemente
cercano al ensamblador como para que sea fcil incluir ensamblado en lnea en un
compilador. En general, esto es ms difcil cuanto ms abstracto es un lenguaje.
La sintaxis depende del compilador. No hay ningn tipo de estandarizacin. De hecho,
la sintaxis de Visual C++ es distinta a la de Borland C++.
El cdigo fuente en lenguaje de alto nivel que contiene instrucciones ensamblado en
lnea no son portales. A veces es preferible mantener separado los fuentes en alto nivel
del lenguaje ensamblador para facilitar la portabilidad. Las tareas para portar el cdigo
slo afectaran, en este caso, al fuente en lenguaje ensamblador.
No suele soportar caractersticas avanzadas de los ensambladores independientes, como
pueden ser el uso de macros o el ensamblado condicional.
Puede afectar a los mecanismos de optimizacin de cdigo del compilador. En los
compiladores actuales, el rendimiento de la optimizacin puede ser menor si el cdigo
fuente contiene construcciones extraas al lenguaje de alto nivel. Puede darse el caso
de que si se incluye ensamblado en lnea el compilador genere peor cdigo (ms
lento, por ejemplo) que si no se usa. De cualquier forma, el grado en que afecta a la
optimizacin es difcil de determinar, pues depende del funcionamiento interno del
compilador, lo cual, por supuesto, no suele estar documentado1.

En cualquier caso, dado la sencillez del ensamblado en lnea, en esta asignatura se va a usar
principalmente para dos tipos de tareas:
Generar programas simples, como los que se van a usar en esta prctica.
Comprobar el funcionamiento de algunas instrucciones del procesador. Cuando se tenga
alguna duda sobre los detalles del funcionamiento de alguna instruccin, no hay ms
que usarla en un bloque __asm y ejecutar el depurador para ver como funciona.

P2.2. Bloques de programacin estructurada.

En esta prctica se va a utilizar ensamblado en lnea para ver como se usan las instrucciones de
comparacin y salto condicional para hacer los principales bloques de programacin estructurada.
La mecnica es la misma para cada uno de los tipos de bloques, y se ilustra con el bloque IF
THEN:

C.1) Bloques IF THE%. Realizar con ensamblado en lnea la parte sombreada del
programa de la figura 2.

1
Hay que tener en cuenta que algunas tcnicas de optimizacin ms avanzadas suelen ser heursticas y muy
complejas. Para los propios diseadores del compilador puede ser muy difcil determinar como pueden afectar el bloque
en ensamblador al cdigo generado. En tal caso, para prevenir efectos inesperados, se desactivan algunas de las
optimizaciones.

3
1: int Entero1, Entero2, Entero3, EnMedio, Maximo, Minimo; // Enteros con signo.
2: void main(void)
3: {
4: int Temporal;
5: Entero2= -4;
6: Entero3= 200;

7: for (Entero1= -1000; Entero1<= 1000; Entero1 ++)


8: if (Entero1 > Entero2) // Entero1 siempre sera menor o igual que Entero2
9: {
10: Temporal=Entero1;
11: Entero1= Entero2;
12: Entero2= Temporal;
13: }
14: }

Fig. 2. Programa de ejemplo para los bloques IF-THE%.

Los elementos de un bloque IF-THEN son:


La condicin, que debe ser evaluada usando comparaciones y saltos condicionales.
El bloque de instrucciones IF. Son las instrucciones que se ejecuta si la condicin es
verdadera.

El siguiente cdigo muestra cmo se trata en ensamblador cada uno de estos elementos:

15: __asm {
16: mov EAX, Entero1 ;TESTEO DE CONDICION
17: cmp EAX, Entero2 s
18: jle fin_if ; SE SALTA CUANDO LA CONDICION ES FALSA
19: mov Temporal, EAX
20: mov EAX, Entero2
21: mov Entero1, EAX INSTRUCCIONES DEL BLOQUE IF
22: mov EAX, Temporal
23: mov Entero2, EAX
24: fin_if:
25: }

La instruccin jle realiza el salto si EAX Entero2, considerando que ambos nmeros son
enteros con signo, de forma que salta todo el bloque IF si la condicin es falsa.
Para comprobar que el cdigo ensamblador es equivalente al C slo hay que insertar un
breakpoint en la lnea 19: El programa debe pararse y el valor de Entero1 y Entero2 debe ser 3 y
4, respectivamente.
Resumiendo, si tenemos un bloque IF-THEN con el siguiente pseudocdigo:
IF <condicin> THE%
<bloque IF>
E%DIF
la mecnica general para pasar de un bloque IF THEN a instrucciones en ensamblador es:

4
<instrucciones de comparacin que testan la condicin>
Jcc END_IF ; salto condicional. cc es el cdigo de condicin para la condicin falsa2.
<instrucciones del bloque if>
END_IF:
<instrucciones que siguen al bloque>

Fig. 3. Esquema general de la traduccin de un bloque IF-THE% a ensamblador.

P2.3. Depuracin en el entorno Visual Studio C++. La ventana de


inspeccin.

Una caracterstica habitual en los depuradores es la posibilidad de inspeccionar y/o


modificar los datos que maneja un programa. Los datos estn en su memoria o en los registros del
procesador, por lo que el depurador debe permitir inspeccionar el contenido de estas zonas. En los
depuradores ms sencillos, suele haber herramientas para mostrar estas zonas (el caso de VC++,
seran las ventanas de registros, y las ventanas de memoria).
Sin embargo, cuando se vuelca el contenido completo de una zona de memoria o registros
se muestra ms informacin de la que realmente usamos: en la ventana de registros aparecen todos
los registros de propsito general, y las de memoria muestran bloques completos de memoria.
Es, por tanto, habitual que un depurador permita alguna forma ms selectiva de
inspeccionar datos. En el caso de VC++, se utilizan las denominadas ventanas de inspeccin
(watch windows).
Para manejar correctamente las herramientas de inspeccin hay que tener en cuenta los
siguientes aspectos:
Condiciones de uso: Cundo se pueden utilizar.
En VC++, por ejemplo, las condiciones ms importantes son:
Debe haberse parado la ejecucin del programa. Slo se puede modificar el contenido
de un dato si el programa ha parado su ejecucin (en un punto de interrupcin, por
ejemplo).
Slo se pueden usar nombres de variables si el depurador dispone de informacin de
depuracin sobre el ejecutable (veremos ms detalles sobre la informacin de
depuracin en el tema 3).

Qu informacin podemos ver y/o modificar.


Aqu es donde ms diferencias puede haber entre distintos depuradores. Aunque en principio,
slo se muestra memoria y registros, hay muchas formas de presentarlos. Las ms tiles suelen ser
en forma de variables que se usan en el programa. Los elementos para los que se utilizan con
mayor frecuencia las ventanas de inspeccin son:
Contenido de las variables: usando el nombre de las mismas.
Registros o partes de un registro: tambin con su nombre.
Direcciones: usando el operador & antes del nombre de la variable.
Estructuras complejas: Vectores, matrices, structs, etc.
Elementos de las estructuras anteriores.

2
Ver la tabla de la transparencia 27 del tema 2 para los distintos tipos de saltos condicionales, en funcin del tipo de
dato y la condicin de salto.

5
Operaciones con variables, elementos de estructuras, direcciones, etc.

Para mostrar las variables, estructuras complejas y/o expresiones se utilizan


expresiones con un formato similar al de las expresiones y operadores de C.

Variable global

Variable local

Direcciones de variables

Registros

Expresiones con direcciones

Vector

Estructura

Expresin con datos

Fig. 4. Ejemplo de expresiones en una ventana de inspeccin.

Formato de la visualizacin.
Es importante, a la hora de evitar confusiones al interpretar la informacin, tener siempre claro
cul es el formato de los datos que se presentan:
Tipo de datos: Los tipos que intervienen en una expresin debe ser compatibles.
o Es recomendable utilizar el casting de expresiones de C.
Formato del dato. El elemento ms importante del formato es la base de numeracin
usada para expresar su valor. La base de numeracin por defecto puede ser decimal o
hexadecimal. Se puede cambiar usando el men desplegable que aparece al pulsar el
botn derecho del ratn sobre la ventana de inspeccin.
o Es posible modificar el formato por defecto de una determinada expresin
usando un operador de formato:
Expresin , Operador_formato.
o Los operadores de formato ms comunes son:

6
Fig. 5. Operadores de formato para las expresiones de la ventana de depuracin.

P2.4. Cuestiones.

C.2) Qu cambios hay que hacer al programa en ensamblador si la comparacin de la


lnea 8: es <=, >, >=, ==, o != ?

C.3) Qu cambios hay que hacer si las todas las variables se definen como unsigned int
en la lnea 1:? Y si se definen como char o unsigned char?

C.4) Supongamos que hacemos los siguientes cambios en el programa de la figura 2:


Entero2 se define como unsigned int.
la lnea 5: (Entero2= -4;) se cambia a Entero2= 4000000000;.
Sigue funcionando correctamente el programa?

C.5) Cambiar la condicin de la lnea 8: por una condicin compuesta y codificarla en


ensamblador (por ejemplo: if ((Entero1 < Entero2) && (Entero1 > Entero3)).

C.6) Realizar un bloque IF THE% ELSE. Dibujar el esquema equivalente al de la


figura 3 para esta estructura.

IF <condicin> THE%
<bloque IF>
ELSE
<bloque ELSE>
E%DIF

C.7) Cambiar el bucle FOR de la figura 2 por una estructura WHILE y codificarla en
ensamblador. Dibujar el esquema equivalente al de la figura 3 para esta estructura.

WHILE <condicin>
<bloque WHILE>
E%DWHILE

C.8) Cambiar el bucle FOR de la figura 2 por una estructura DO WHILE y codificarla
en ensamblador. Dibujar el esquema equivalente al de la figura 3 para esta estructura.

DO
<bloque REPEAT>
WHILE <condicin>

C.9) Codificar en ensamblador la estructura FOR de la figura 2. Dibujar el esquema


equivalente al de la figura 3 para esta estructura.

FOR <condicin inicial>, <condicin final>, <condicin del bucle>


<bloque FOR>

You might also like