Objetivo. Introducción. Tema: GENERACION DE CODIGO. Compiladores, Guía 11 1

Compiladores, Guía 11 1 Facultad : Ingeniería Escuela :Computación Asignatura:Compiladores Tema: “GENERACION DE CODIGO”. Objetivo • Reconocer las diferentes instrucciones para la generación de código.ensamblador • Realizar segmetos de codigo a traves de ejemplos de ASM embebido en C++. Introducción El lenguaje ensamblador que se utiliza para traducir programas al código de máquina. Cada microprocesador o microcontrolador tiene su propio lenguaje ensamblador con su particular conjunto de instrucciones y sus varios modos de direccionamiento que dependen de la arquitectura del hardware, cada nuevo procesador de INTEL que sale al mercado, el fabricante agrega algunas instrucciones a su conjunto de instrucciones, pero siempre conservan las instrucciones y registros de los modelos anteriores por razones de compatibilidad. Registros del procesador Los primeros procesadores proveían registros de 16 bits AX, BX, CX, DX, SI, DI, BP, SP, CS, DS, SS, ES, IP, y FLAGS. El procesador soportaba hasta 1Mb de memoria y solo podía operar en modo Real. En este modo el programa podía acceder a cualquier dirección de memoria, incluso a direcciones utilizadas por otros programas. Sus cuatro registros principales, AX, BX, CX, y DX están divididos en dos registros de 8 bits cada uno. En la Fig. 1 se puede observar el registro AX que posee una parte que contiene los primeros 8 bits denominada AH (high) y una parte que contiene los últimos 8 bits denominada AL (low), y así sucesivamente con cada uno de los registros mencionados. 16 bits 8 bits 8 bits AX AH AL BX BH BL CX CH CL DX DH DL Fig. 1 Compiladores, Guía 11 2 Este tipo de registros se usa especialmente en operaciones aritméticas, ya que nos permite manejarnos con comodidad cuando trabajamos con datos que no superan un byte, pero se debe tener cuidado ya que AH y AL no son independientes de AX, o sea que si hacemos algún movimiento de datos referenciando a AX, también estamos cambiando los valores de AH y AL. Los registros SI y DI son utilizados generalmente como punteros. Los registros BP y SP se conocen como los punteros de pila. Se utilizan para moverse dentro de la pila. CS, DS, SS, y ES son los segments registers. Son los encargados de direccionar las distintas partes de cada programa: CS para el code segment, donde se guardan los datos del código de máquina de las instrucciones que constituyen el programa. DS para el data segment, que guarda los datos que el programa debe operar y los resultados de la ejecución del mismo. SS para el stack segment, Almacena datos y direcciones necesarias durante la ejecución de cada parte del programa y que es localizada dentro del segmento mediante el registro SP (stack pointer). ES para el extra segment, utilizado para guardar datos tipo strings, también como prolongación del DS (data segment), y como registro temporal. Cada dato es apuntado dentro del segmento por el registro puntero DI. El registro IP es utilizado para mantener una pista de la dirección de la próxima instrucción a ejecutarse por el procesador. Normalmente cuando se ejecuta una instrucción, IP se adelanta a apuntar a la próxima instrucción en memoria. El FLAGS es un registro de 16 bits que se divide en 16 partes de 1 bit. Cada uno de estos bits guarda información importante sobre el resultado de la instrucción anterior. Este resultado se guarda con un solo un bit que puede ser 1 ó 0. Por ejemplo, el bit Z es 1 si el resultado de la instrucción anterior fue 0, y es 0 si el resultado fue 1. El bit C será 1 si la última operación produjo acarreo, y 0 si no lo hizo. A partir del procesador 80386 se produce un salto en el diseño. Extendiendo la mayoría de sus registros a 32 bits y renombrándolos como EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP y agregan también dos registros nuevos de 16 bits denominados FS y GS. Para guardar compatibilidad con los diseños anteriores se conviene de que al hacer referencia a AX, se hace referencia a los últimos 16 bits de EAX (lo mismo que era AL de AX); pero no se puede tener acceso directo a los primeros 16 bits de EAX. Instrucciones de lenguaje ensamblador: Instrucción MOV: La función de la instrucción MOV, es como su nombre da a entender, "mover" un valor. Por ejemplo: MOV AX,BX Esta instrucción copia el contenido de BX en AX, conservando el valor de BX. Otro ejemplo: MOV AX,2000 MOV [A100],AX En este caso introducimos el valor 2000 en AX, y luego lo llevamos a la dirección de memoria A100. Compiladores. Guía 11 3 Con la instrucción MOV se puede realizar las siguientes operaciones: Tipo de operación MOV registro,registro MOV memoria,registro MOV registro,memoria MOV registro,constante Ejemplo MOV AX,BX MOV [2000],AX MOV BX,[1500] MOV AX,1000 Fig. 2 Instrucciones INC y DEC: Son las más básicas a la hora de hacer operaciones con registros: INC, incrementa el valor de un registro o de cualquier posición de memoria en una unidad. DEC, lo decrementa un registro en el mismo valor. Ejemplos: INC AX DEC AX Incrementa en una unidad el valor de AX y lo decrementa, por lo que no ha cambiado su valor. Estas dos instrucciones nos van a servir mucho en el uso de contadores en los bucles. Son equivalentes a ++ y -- del lenguaje C/C++. Instrucciones ADD y SUB: Se trata de dos operadores que contienen todos los lenguajes de programación: la suma y la resta. Tienen dos operandos, uno de destino y otro fuente. Para la suma, se suman los dos operandos y se almacena el resultado en el primero (destino). Para la resta, se le resta al primero el segundo, y se almacena el resultado en el primero (destino). Ejemplos: ADD AX,BX ;Suma a AX con BX, y lo guarda en AX. (AX+BX) -> AX ADD AX,[SI] ;Se suman AX y el contenido de lo que esta apuntado por SI y se almacena en AX. ADD AX,3 ;Suma 3 a AX y lo almacena en AX. (AX+3) -> AX SUB AX,AX ;Resta AX de AX. Se utiliza para poner a AX en 0. SUB CX,DX ;Se resta el valor de CX con DX y se almacena en CX. SUB CX,20 ;Se resta de CX el valor 20, y queda en CX el resultado. Nota: el uso de la “;” es para hacer comentarios. Compiladores, Guía 11 4 Materiales y equipo Guia de Laboratorio Nº11 Dev C++. Procedimiento Desarrolle el siguiente programa de C++ con ensamblador emebido: #include #include using namespace std; int a; int b; main() { asm("movl $9, %eax"); asm("subl $4, %eax"); asm("movl %eax, printf("a = _a"); %d\n", a); asm("movl $3, %eax"); asm("addl $9, %eax"); asm("movl %eax,

14 downloads 115 Views 327KB Size

Story Transcript

Compiladores, Guía 11 1 Facultad : Ingeniería Escuela :Computación Asignatura:Compiladores

Tema: “GENERACION DE CODIGO”.

Objetivo •

Reconocer las diferentes instrucciones para la generación de código.ensamblador



Realizar segmetos de codigo a traves de ejemplos de ASM embebido en C++.

Introducción El lenguaje ensamblador que se utiliza para traducir programas al código de máquina. Cada microprocesador o microcontrolador tiene su propio lenguaje ensamblador con su particular conjunto de instrucciones y sus varios modos de direccionamiento que dependen de la arquitectura del hardware, cada nuevo procesador de INTEL que sale al mercado, el fabricante agrega algunas instrucciones a su conjunto de instrucciones, pero siempre conservan las instrucciones y registros de los modelos anteriores por razones de compatibilidad. Registros del procesador Los primeros procesadores proveían registros de 16 bits AX, BX, CX, DX, SI, DI, BP, SP, CS, DS, SS, ES, IP, y FLAGS. El procesador soportaba hasta 1Mb de memoria y solo podía operar en modo Real. En este modo el programa podía acceder a cualquier dirección de memoria, incluso a direcciones utilizadas por otros programas. Sus cuatro registros principales, AX, BX, CX, y DX están divididos en dos registros de 8 bits cada uno. En la Fig. 1 se puede observar el registro AX que posee una parte que contiene los primeros 8 bits denominada AH (high) y una parte que contiene los últimos 8 bits denominada AL (low), y así sucesivamente con cada uno de los registros mencionados.

16 bits 8 bits

8 bits

AX

AH

AL

BX

BH

BL

CX

CH

CL

DX

DH

DL

Fig. 1

Compiladores, Guía 11

2

Este tipo de registros se usa especialmente en operaciones aritméticas, ya que nos permite manejarnos con comodidad cuando trabajamos con datos que no superan un byte, pero se debe tener cuidado ya que AH y AL no son independientes de AX, o sea que si hacemos algún movimiento de datos referenciando a AX, también estamos cambiando los valores de AH y AL. Los registros SI y DI son utilizados generalmente como punteros. Los registros BP y SP se conocen como los punteros de pila. Se utilizan para moverse dentro de la pila. CS, DS, SS, y ES son los segments registers. Son los encargados de direccionar las distintas partes de cada programa: CS para el code segment, donde se guardan los datos del código de máquina de las instrucciones que constituyen el programa. DS para el data segment, que guarda los datos que el programa debe operar y los resultados de la ejecución del mismo. SS para el stack segment, Almacena datos y direcciones necesarias durante la ejecución de cada parte del programa y que es localizada dentro del segmento mediante el registro SP (stack pointer). ES para el extra segment, utilizado para guardar datos tipo strings, también como prolongación del DS (data segment), y como registro temporal. Cada dato es apuntado dentro del segmento por el registro puntero DI. El registro IP es utilizado para mantener una pista de la dirección de la próxima instrucción a ejecutarse por el procesador. Normalmente cuando se ejecuta una instrucción, IP se adelanta a apuntar a la próxima instrucción en memoria. El FLAGS es un registro de 16 bits que se divide en 16 partes de 1 bit. Cada uno de estos bits guarda información importante sobre el resultado de la instrucción anterior. Este resultado se guarda con un solo un bit que puede ser 1 ó 0. Por ejemplo, el bit Z es 1 si el resultado de la instrucción anterior fue 0, y es 0 si el resultado fue 1. El bit C será 1 si la última operación produjo acarreo, y 0 si no lo hizo. A partir del procesador 80386 se produce un salto en el diseño. Extendiendo la mayoría de sus registros a 32 bits y renombrándolos como EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP y agregan también dos registros nuevos de 16 bits denominados FS y GS. Para guardar compatibilidad con los diseños anteriores se conviene de que al hacer referencia a AX, se hace referencia a los últimos 16 bits de EAX (lo mismo que era AL de AX); pero no se puede tener acceso directo a los primeros 16 bits de EAX.

Instrucciones de lenguaje ensamblador: Instrucción MOV: La función de la instrucción MOV, es como su nombre da a entender, "mover" un valor. Por ejemplo: MOV AX,BX Esta instrucción copia el contenido de BX en AX, conservando el valor de BX. Otro ejemplo: MOV AX,2000 MOV [A100],AX En este caso introducimos el valor 2000 en AX, y luego lo llevamos a la dirección de memoria A100.

Compiladores. Guía 11

3

Con la instrucción MOV se puede realizar las siguientes operaciones: Tipo de operación MOV registro,registro MOV memoria,registro MOV registro,memoria MOV registro,constante

Ejemplo MOV AX,BX MOV [2000],AX MOV BX,[1500] MOV AX,1000 Fig. 2

Instrucciones INC y DEC: Son las más básicas a la hora de hacer operaciones con registros: INC, incrementa el valor de un registro o de cualquier posición de memoria en una unidad. DEC, lo decrementa un registro en el mismo valor. Ejemplos: INC AX DEC AX Incrementa en una unidad el valor de AX y lo decrementa, por lo que no ha cambiado su valor. Estas dos instrucciones nos van a servir mucho en el uso de contadores en los bucles. Son equivalentes a ++ y -- del lenguaje C/C++. Instrucciones ADD y SUB: Se trata de dos operadores que contienen todos los lenguajes de programación: la suma y la resta. Tienen dos operandos, uno de destino y otro fuente. Para la suma, se suman los dos operandos y se almacena el resultado en el primero (destino). Para la resta, se le resta al primero el segundo, y se almacena el resultado en el primero (destino). Ejemplos: ADD AX,BX

;Suma a AX con BX, y lo guarda en AX. (AX+BX) -> AX

ADD AX,[SI]

;Se suman AX y el contenido de lo que esta apuntado por SI y se almacena en AX.

ADD AX,3

;Suma 3 a AX y lo almacena en AX. (AX+3) -> AX

SUB AX,AX

;Resta AX de AX. Se utiliza para poner a AX en 0.

SUB CX,DX

;Se resta el valor de CX con DX y se almacena en CX.

SUB CX,20

;Se resta de CX el valor 20, y queda en CX el resultado.

Nota: el uso de la “;” es para hacer comentarios.

Compiladores, Guía 11

4

Materiales y equipo Guia de Laboratorio Nº11 Dev C++.

Procedimiento Desarrolle el siguiente programa de C++ con ensamblador emebido:

#include #include using namespace std; int a; int b; main() { asm("movl $9, %eax"); asm("subl $4, %eax"); asm("movl %eax, printf("a =

_a");

%d\n", a);

asm("movl $3, %eax"); asm("addl $9, %eax"); asm("movl %eax, printf("b =

_b");

%d\n", b);

system("PAUSE"); return 0; }

Debe notar que las variables gobales a y b declaradas dendtro del código ensamblador se denotan como _a y _b

Compiladores, Guía 11 5

Ejecute el programa siguiente, observe el resultado y justifique la forma de implentar código embebido: #include #include using namespace std; int a=3; int b=9; main() { asm("movl _b, %eax"); asm("subl _a, %eax"); asm("movl %eax, printf("a =

_a");

%d\n", a);

asm("movl _b, %eax"); asm("addl _a, %eax"); asm("movl %eax, printf("b =

%d\n", b);

system("PAUSE"); return 0; }

_b");

Compiladores, Guía 11

6

Ejecute tambien el programa siguiente, observe el resultado y justifique la forma de implentar código embebido:

#include #include using namespace std; int a=3; int b=9; main() { asm("movl _a, %eax"); asm("movl _b, %ebx"); asm("mul %ebx"); asm("mov %eax, _a"); printf("

%d\n", a);

system("PAUSE"); return 0; }

Compiladores, Guía 11

Como se puede hacer mejoras al programa siguiente:

#include #include using namespace std; int a=3; int b=20; int c=7; int d=1; int e=0; main() { asm("movl _a, %eax"); asm("add _b, %eax"); asm("add _c, %eax"); asm("add _d, %eax"); asm("movl $4, %ecx"); asm("cltd"); asm("divl %ecx"); asm("mov %eax, _c"); asm("movl %edx, _e"); printf("

%d\n", c);

printf(" %d\n", e); system("PAUSE"); return 0; }

7

Compiladores, Guía 11

8

Análisis de resultados Se pide los programas que generen código ensamblador para: 1. sentencias condicionales if (i

2

j > 7) {

else { }



2. sentencias repetitivas for for (inicial; condicion; incremento ) { }

3. sentencias repetitivas while. while (inicial ) { }

Compiladores. Guía 11

9

Investigación complementaria. Programas que generen código ensamblador para funciones y modificar el generador de código intermedio de la guia N’ 10 para generar ensamblador.

Referencia. http://www.gui.uva.es/udigital/ http://repositori.uji.es/xmlui/bitstream/handle/10234/5916/codigo.apun.pdf?sequence=1

Compiladores, Guía 11

10

Hoja de cotejo:

11

Guía 11: Generación de Código. Alumno:

Máquina No:

Docente:

GL:

Fecha:

EVALUACION %

CONOCIMIENTO

40

APLICACIÓN DEL CONOCIMIENTO

40

ACTITUD

20

TOTAL 100%

1-4

5-7

8-10

Nota

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.