Arquitectura de Computadores

Arquitectura de Computadores 3. Lenguaje Máquina 1. Visión del Programador 2. Formato de las Instrucciones 3. Modos de Direccionamiento 4. Instruccion

1 downloads 191 Views 297KB Size

Recommend Stories


Arquitectura de Computadores
Arquitectura de Computadores 8. Arquitecturas RISC 1. Evolución de los CISC 2. Análisis de los Programas 3. Principios y Características de las Arquit

Arquitectura de Computadores
Arquitectura de Computadores TEMA 3 Lanzamiento múltiple, Límites de ILP, Multithreading Curso 2012-2013 Contenidos o Introducción: CPI < 1 o Lanz

Arquitectura de Computadores
Arquitectura de Computadores Entrega 1 En el siguiente informe detallamos el proyecto que realizaremos como grupo durante el siguiente semestre. Consi

Story Transcript

Arquitectura de Computadores 3. Lenguaje Máquina 1. Visión del Programador 2. Formato de las Instrucciones 3. Modos de Direccionamiento 4. Instrucciones Típicas 5. Un Ejemplo: Motorola 68000 Arquitectura de Computadores

Lenguaje Máquina - 1

En el capítulo anterior hemos visto la interfaz hardware que ofrece la CPU, esto es, los elementos que ofrece para conectarla con el resto de los componentes de un ordenador. Ahora abordaremos la interfaz software, o lo que es lo mismo, lo que necesitan saber los programadores o constructores de compiladores para poder escribir programas capaces de ejecutarse en la CPU. Esta interfaz software muestra aspectos como el repertorio y formato de las instrucciones que ofrece, con sus variados modos de direccionamiento para acceso a los operandos. Pero para poder escribir programas para una CPU también se necesita conocer otros aspectos como los registros internos, estructura o visión de la memoria y los tipos de datos que maneja directamente la ALU. Después de dar una introducción general a estos aspectos, se verá con cierto detalle un caso concreto: el procesador 68000 de Motorola.

Arquitectura de Computadores

Lenguaje Máquina - 1

Visión del Programador

Lenguaje Máquina

Visión del Hardware

CPU PC SP SR R0 ...

0400 10FF

Memoria $0000 $0001 $0400 $0B00

Rn

$1000

Bus Datos (x bits)

Bus Dir. (y bits)

prog. datos

2y

pila

$10FF $FFFF

x Arquitectura de Computadores

Lenguaje Máquina - 2

El programador más inmediato de un ordenador trabaja a muy bajo nivel, pues ve el hardware muy de cerca. Los programas los tiene que escribir en lenguaje máquina o, normalmente, en ensamblador, es decir, una representación nemotécnica del lenguaje máquina en la que cada instrucción ensamblador se corresponde con una instrucción máquina. ¿Qué tiene que conocer este programador de ensamblador o de lenguaje máquina para escribir programas para el ordenador? La respuesta es “Algo de hardware y algo de software”. 1) Algo de hardware: • Algunos detalles de la CPU: - Registros generales y de control (Contador de Programa, Puntero de Pila, Registro de Estado, ...). - Tamaño de los registros generales, para saber el rango de los números que se pueden manejar. • Tamaño de la memoria

Arquitectura de Computadores

Lenguaje Máquina - 2

…Visión del Programador

Lenguaje Máquina

Visión del Software

Pila E1

Juego de Instrucciones Nemotécnico move #3,R2 add R2,R3 ...

50

Cod. Máquina 11000111 ($C7) 00110110 ($36)

2B 9A

... sub #1,R2

01100110 ($66)

LIFO

Arquitectura de Computadores

- Meter - Sacar Lenguaje Máquina - 3

2) Algo de software: • El juego de instrucciones • Organización de la pila (si la hay). Estos elementos de hardware y de software son con los que cuenta el programador para escribir sus programas, o lo que es lo mismo, ésta es la visión del programador del ordenador básico. En resumen, cuenta con una memoria donde almacena su programa (con las instrucciones y los datos) y una CPU que es capaz ejecutar las instrucciones del programa, ayudándose para ello de registros internos a los que trae los operandos desde la memoria principal, y de una pila para guardar ciertos datos temporales. Puesto que ya conocemos la estructura básica de una CPU, en este capítulo vamos ocuparnos del lenguaje máquina, es decir, del formato que pueden tener las instrucciones máquina, de los modos de direccionamiento disponibles para acceder a los operandos indicados en las instrucciones y, por supuesto, de los distintos tipos de instrucciones que suelen ofrecer los procesadores de propósito general (al menos los de tipo CISC). Al final del capítulo particularizaremos todo esto para el microprocesador de Motorola MC68000, comentando su estructura general, organización de la memoria, su pila y, por supuesto, su juego de instrucciones.

Arquitectura de Computadores

Lenguaje Máquina - 3

Formato de las Instrucciones

Lenguaje Máquina

Cod. Op. Cod. Op.

Operando

Cod. Op.

Operando 1

Operando 2

- Valor - Dirección · memoria · registro

Arquitectura de Computadores

Lenguaje Máquina - 4

Una instrucción máquina es una secuencia de bits que indica una operación que debe realizarse y con qué operandos debe realizarse. Los operandos son datos que están en alguno de los registros internos de la CPU, en la memoria principal o en algún controlador de entrada/salida. Una instrucción siempre realiza alguna acción sobre algún o algunos operandos. Estos pueden estar indicados implícita o explícitamente en la instrucción máquina. Un operando está implícito en una instrucción cuando el propio código de operación establece sobre qué actúa la operación. En este caso, tal operando es fijo, es decir, el programador no puede establecer que esa instrucción actúe con otro operando distinto. Cuando una instrucción puede operar con diversos operandos posibles, a elegir por el programador, los operandos elegidos deben figurar de manera explícita (separados del código de operación) en la instrucción máquina. Si una instrucción utiliza varios operandos, estos pueden ser una mezcla de operandos implícitos y explícitos. El formato de una instrucción máquina define la disposición y el reparto de sus bits entre los componentes de la instrucción, esto es, el código de operación y los operandos. Una instrucción máquina debe incluir el código de operación y, si los tiene, uno o más operandos explícitos. A cada operando explícito se accede mediante uno de los distintos modos de direccionamiento que veremos en el siguiente apartado. Como veremos más tarde (al comentar los distintos tipos de instrucciones que se suelen encontrar en los procesadores de propósito general) ya que hay instrucciones con uno, dos, tres o ningún operando explícito, es normal que los juegos de instrucciones estén compuestos por instrucciones con distintos formatos. En el formato de cada instrucción se suele indicar implícita o explícitamente el modo de direccionamiento de cada uno de sus operandos.

Arquitectura de Computadores

Lenguaje Máquina - 4

Lenguaje Máquina

Longitud de Instrucción

Cuestiones de Diseño

Muchos códigos de operación Muchos modos de direccionamiento

Instrucción más larga

Gran espacio de direcciones Long. instrucción múltiplo de palabra

Reparto de Bits

Más memoria Más lento

¿Cuántos códigos de operación? ¿Cuántos operandos? ¿Dónde están los operandos? ¿Cuántos registros hay?

¡ COMPROMISO !

¿Cuántos modos de direccionamiento? ¿Granularidad de las direcciones? Arquitectura de Computadores

Lenguaje Máquina - 5

A la hora de diseñar un juego de instrucciones, se deben tener en cuenta ciertas consideraciones sobre dos cuestiones: la longitud de la instrucción y el reparto de los bits que la componen. Longitud de la instrucción. Hay un claro compromiso entre el deseo de un rico y variado repertorio de instrucciones, y la necesidad de ahorrar espacio. Los programadores quieren muchos códigos de operación distintos (requiere muchos bits en el campo de código de operación) para disponer de operaciones que se ajusten lo más posible a sus necesidades, y así escribir programas más cortos. De igual manera, cuantos más modos de direccionamiento estén disponibles, más flexibilidad tendrán para manejar estructuras de datos complejas, como tablas o matrices. Por otro lado, puesto que cada vez se dispone de mayor cantidad de memoria, se requieren muchos bits para hacer referencia a un gran espacio de direccionamiento. Pero claro, una instrucción que ofrezca todo esto puede ocupar 32 bits, posiblemente, el doble que otra similar que no ofrezca tanta flexibilidad. Está claro que una instrucción larga ocupa más espacio en memoria que una corta, se tarda más tiempo en llevarla de memoria a la CPU, y se tarda más tiempo en decodificarla. Se debe tener en cuenta que el ancho del bus de datos sea múltiplo de la longitud de un carácter, para evitar desaprovechar el espacio de almacenamiento. Y esta restricción afecta a la longitud de las instrucciones, que deben ocupar un número entero de palabras, o en una palabra debe caber un número entero de instrucciones. Por esto los tamaños de las instrucciones suelen ser múltiplos de 8. Un diseño con caracteres de 9 bits, instrucciones de 12 y palabras de 31 bits sería una catástrofe. Reparto de los bits. Aquí el compromiso está en el reparto de los bits disponibles entre el número de códigos de operación y la versatilidad de los operandos. Esta versatilidad genera las siguientes preguntas: ¿cuántos operandos hay en la instrucción?, ¿de cuántos modos de direccionamiento se dispone?, ¿dónde están los operandos, en registros o en memoria?, ¿cuántos registros hay?. El direccionamiento a memoria también plantea una pregunta: ¿cuál es la granularidad de las direcciones?. Es decir, ¿a dónde apunta cada dirección, a un byte, a una palabra de 16 bits, a una palabra de 32 bits, ...? Si el grano es de 1 byte, para direccionar una memoria de 64 Kb se requieren 16 bits, mientras que si el grano fuera una palabra de 4 bytes, solo se necesitarían 14 bits, lo cual significa instrucciones más cortas, menor espacio para el programa, y un menor tiempo para alimentar la instrucción. Sin embargo, tiene la pega de que para obtener un carácter de memoria hay que acceder a la palabra completa, y luego en la CPU seleccionar la parte deseada, lo cual consume tiempo.

Arquitectura de Computadores

Lenguaje Máquina - 5

Códigos de Operación con Extensión

Lenguaje Máquina

OTRO CASO

Intel -Motorola

Instrucciones de 16 bits

Instrucción de Longitud variable

Hasta 3 operandos en 16 registros Hasta 16 operaciones distintas

PowerPC Formato fijo C. op.

Operandos

6

26

¡ PERO NECESITAMOS ! 15 Instrucciones de 3 operandos 14



de 2



31



de 1



16



sin operandos

¿Cómo? Arquitectura de Computadores

Lenguaje Máquina - 6

Debido a los compromisos que acabamos de ver, normalmente todos los juegos de instrucciones son de longitud variable, es decir, disponen de diversos formatos de instrucción, con distintas longitudes que se adaptan a las necesidades de la instrucción. Por esto, es normal encontrarse que en una misma máquina hay instrucciones de 1, 2, 3 y 4 o más bytes de longitud (eso sí, siempre con un tamaño múltiplo de 8 bits). El Pentium de Intel, tiene instrucciones de longitud variable, y pueden llegar a tener un tamaño de hasta 12 bytes. El PowerPC, por el contrario, tiene un juego de instrucciones con un formato regular de 32 bits, donde los 6 primeros corresponden al código de operación. Hasta ahora hemos supuesto que una vez decidido el número de bits reservado para el código de operación, tanto este número como el reservado para los operandos es fijo. Por ejemplo, si una CPU ofrece 100 instrucciones, parece que el código de operación debe tener reservados 7 bits en la instrucción. Pero en algunas arquitecturas en las que las instrucciones son de longitud fija (como en el PowerPC), puede resultar conveniente hacer variable el tamaño del código de operación, para acomodarse a las necesidades de la instrucción. Veámoslo con un ejemplo. Supongamos una máquina con instrucciones de 16 bits, que realiza operaciones hasta con 3 operandos, y que éstos siempre están en alguno de sus 16 registros. Esto quiere decir que se necesitan 4 bits por operando, y que si puede haber hasta 3 operandos, se necesitan 12 bits para ellos. Esto nos deja con 4 bits para códigos de operación, lo que significa que puede haber hasta 16 operaciones distintas con 3 operandos. Pero resulta que lo que se desea es un juego con 15 instrucciones de 3 operandos, 14 instrucciones de dos operandos, 31 de un operando, y 16 instrucciones sin operandos. ¿Cómo hacerlo? Con Códigos de Operación con Extensión. En la siguiente transparencia tenemos la solución. Los códigos de operación con extensión son bastante comunes. No solamente los utilizan procesadores con formatos instrucción de longitud fija, como el PowerPC, sino los de longitud variable como el 80386, 80486 y Pentium de Intel, y la familia 68000 de Motorola.

Arquitectura de Computadores

Lenguaje Máquina - 6

…Códigos de Operación con Extensión

Lenguaje Máquina

Cod. Op. de 4 bits

Cod. Op. de 8 bits

15 instrucciones de 3 operandos 0000 0001 0010 . . . . . . 1101 1110

XXXX XXXX XXXX . . . XXXX XXXX

YYYY YYYY YYYY

ZZZZ ZZZZ ZZZZ

YYYY YYYY

ZZZZ ZZZZ

14 instrucciones de 2 operandos 1111 1111 1111 . . . . . . 1111 1111

0000 0001 0010 . . . 1100 1101

Arquitectura de Computadores

XXXX XXXX XXXX

XXXX XXXX

YYYY YYYY YYYY

YYYY YYYY

Cod. Op. de 12 bits

Cod. Op. de 16 bits

31 instrucciones de 1 operando 1111 1111 . . 1111 1111 1111 . . 1111 1111

1110 1110 . 1110 1111 1111 . 1111 1111

0000 0001

XXXX XXXX

1111 0000 0001

XXXX XXXX XXXX

1101 1110

XXXX XXXX

16 instrucciones sin operandos 1111 1111 1111 . . . . 1111 1111 1111

1111 1111 1111 . . 1111 1111 1111

1111 1111 1111

0000 0001 0010

1111 1111 1111

1101 1110 1111

Lenguaje Máquina - 7

15 instrucciones de 3 operandos. Comencemos con el formato de las 15 instrucciones de 3 operandos de 4 bits. No tenemos ningún problema, pues para representar 15 códigos de operación se requieren 4 bits, y los 12 bits restantes se utilizan para los tres operandos de 4 bits. Así, los códigos de operación serán el 0000, 0001, ..., hasta el 1110. ¡Y nos sobra una combinación de las 165 que ofrecen 4 bits! 14 instrucciones de 2 operandos. La combinación que nos sobraba del formato anterior (la 1111) la utilizaremos ahora para indicar un nuevo formato de instrucción. Es decir, las instrucciones cuyos 4 bits de mayor peso sean 1111 tendrán un código de operación extendido con los 4 bits siguientes. En este nuevo formato, el código de operación ocupa 8 bits, donde los 4 de mayor peso están siempre a 1. Los ocho bits restantes se utilizan para indicar los dos operandos de este formato. Ahora nos encontramos con que también nos sobran dos combinaciones: 1111 1110 y 1111 1111. Las aprovecharemos. 31 instrucciones de 1 operando. Si los cuatro bits de mayor peso a 1 indican que el código de operación se extiende o amplía con otros cuatro, cuando los 7 bits de mayor peso son 1111 111, indica que el formato de tales instrucciones está formado por un código de operación de 12 bits (los de mayor peso). Los cuatro bits restantes se utilizan como operando. Para este formato disponemos ahora de 5 bits para expresar 31 nuevas instrucciones, las que tienen los códigos desde 1111 1110 0000 hasta 1111 1111 1110. Ahora nos sobra una combinación de las disponibles. 16 instrucciones sin operandos explícitos. Como vamos viendo, el que sobre alguna combinación no es casualidad o buena suerte, simplemente es que es necesario para poder seguir extendiendo el código de operación. Ahora nos encontramos con que los doce bits de mayor peso a 1 indican un nuevo formato de instrucción con un código de operación de 16 bits. Los cuatro bits de la ampliación son los que nos ofrecen los últimos 16 códigos de operación para las instrucciones sin operandos explícitos. Cuando se planifican formatos de instrucciones con códigos de operación con extensión, para cada formato, se debe reservar alguna de las combinaciones posibles para expresar una extensión en el código de operación.

Arquitectura de Computadores

Lenguaje Máquina - 7

Modos de Direccionamiento

Lenguaje Máquina

 ¿Dónde se Ubican los Operandos? ADD #7,R4,$FF1234

En la Instrucción ☺ Rápido y simple Sólo constantes No para resultados

En Memoria Principal Muchos bits

En Registros de la CPU ☺ Se requieren pocos bits ☺ Rápido acceso Pocos registros Hay que cargar los registros Arquitectura de Computadores

Lenguaje Máquina - 8

El diseño cuidadoso de los códigos de operación es una parte importante del juego de instrucciones de una máquina. No obstante, la mayor parte de los bits de una instrucción se utilizan para especificar los operandos de la operación, por lo que también debe afrontarse con mucho cuidado el modo de direccionar los operandos de las instrucciones. Vamos a considerar ahora dos factores sobre los operandos a tener en cuenta en el diseño del formato de las instrucciones: • Dónde poner los operandos • Cuántos operandos se indican en la instrucción Los operandos pueden estar en tres sitios: • En la propia instrucción • En registros de la CPU • En memoria principal Con el operando en la misma instrucción, parece claro que el acceso a él es simple y rápido, no obstante estos operandos solamente pueden ser constantes, pues su valor se establece en tiempo de compilación; por esto mismo, tampoco se pueden utilizar como operandos de destino o de resultado. Así, si las variables están ubicadas en memoria principal, parece conveniente utilizar el campo de operando para indicar su dirección en memoria principal, sin embargo, para los procesadores actuales, es normal disponer de un bus de direcciones de 32 bits, lo que implica que el campo de operando en la instrucción requiere también 32 bits, y si consideramos una instrucción con tres operandos más el código de la operación, la longitud de la instrucción se dispara. Una alternativa puede ser utilizar registros generales para contener los operandos. Así, en una máquina con 8 registros se necesitan solamente 3 bits para indicar uno de ellos en el campo de operando. Esto tendría la mejora añadida de que el acceso a un registro es mucho más rápido que a memoria principal. Pero también tiene pegas. Una es que si se dispone de pocos registros generales y se ubican en ellos las variables, se pueden agotar enseguida. Por esto, las arquitecturas recientes tienden proporcionar un número generoso de registros. Otra pega es que para operar con operandos en registros, previamente hay que cargarlos desde memoria principal, lo que significa ejecutar instrucciones adicionales con direcciones de memoria (largas y costosas). Por esto, solamente merece la pena cargar los operandos en registros cuando se van a utilizar repetidamente (lo cual suele ser lo más habitual).

Arquitectura de Computadores

Lenguaje Máquina - 8

…Modos de Direccionamiento

Lenguaje Máquina

 ¿Cuántos Operandos se Indican en la Instrucción? Todos ADD $FF1234,$FFF123,$FFFF12 Requiere muchos bits

Reutilizar Alguno ADD $FF1234,$FFF123

Omitir Alguno (Implícitos) - En Acumulador: ADD $FF1234 - En la Pila: PUSH R1 Arquitectura de Computadores

Lenguaje Máquina - 9

En cuanto al número de operandos, algunas instrucciones pueden requerir tres operandos, como la suma (dos sumandos y un resultado), lo cual puede resultar en un exceso de bits. Por ello, la mayoría de este tipo de instrucciones suele utilizar como resultado uno de los mismos operandos, ahorrando así espacio en la instrucción. Otra posibilidad consiste en no indicar los operandos explícitamente en la instrucción, utilizando directamente ciertos operandos de forma implícita. Así, algunas máquinas indican un único operando para realizar una suma, y lo que hacen es añadir el contenido de ese operando al de un registro especial llamado acumulador, y el resultado lo dejan también en el acumulador. El problema que presenta esta última técnica es que cuando hay muchos cálculos, hay que estar constantemente cargando y salvando el contenido del acumulador, lo cual requiere espacio de instrucciones y tiempo de ejecución. Otro modo de indicar operandos implícitos es con los direccionamientos orientados a Pila que veremos en las siguientes transparencias.

Arquitectura de Computadores

Lenguaje Máquina - 9

Inmediato

Modos de Direccionamiento

MOV_AC #47 C. Op.

Operando

Constantes “pequeñas” Números en complemento a dos ☺ Sin referencias a memoria

Arquitectura de Computadores

Lenguaje Máquina - 10

Como ya hemos mencionado, el espacio disponible para los operandos en una instrucción suele estar bastante limitado. También sabemos que los datos con los que hay que operar pueden encontrarse en los registros del procesador, en variables de la memoria principal o en la pila. Por otra parte, dependiendo de la complejidad de las estructuras de datos manejadas se puede hacer necesaria la utilización de modos de direccionamiento más o menos complejos. Algunas veces el modo del direccionamiento viene indicado implícitamente por el código de operación, que fuerza el modo de direccionamiento, en otros casos el modo debe indicarse explícitamente en cada operando. Vamos a dedicarnos ahora a tratar algunos modos de direccionamiento más comunes que suelen encontrarse en los procesadores de propósito general. Aunque hay múltiples variaciones, todas ellas suelen estar basadas en los modos que vamos a tratar a continuación. Direccionamiento Inmediato La forma más simple de indicar un operando es incluyéndolo en la propia instrucción. Ya que las instrucciones no son modificables, este es el modo que se utiliza en operaciones con constantes. Si la constante es un valor numérico, se almacena en complemento a dos. La ventaja del direccionamiento inmediato es que no se requieren referencias adicionales a memoria para obtener el operando, ahorrando por lo tanto espacio y tiempo. El inconveniente es que el espacio reservado para este operando suele estar restringido y suele ser menor que el tamaño de la palabra, por lo que en algunos procesadores solamente se utiliza para constantes de valores pequeños.

Arquitectura de Computadores

Lenguaje Máquina - 10

Directo

Modos de Direccionamiento

INC $10B0 C. Op.

dddddddddddddddd

....

operando

Para las variables globales Una referencia adicional a memoria

MEMORIA

Requiere muchos bits

Arquitectura de Computadores

Lenguaje Máquina - 11

Direccionamiento Directo (o absoluto) Otra forma muy simple de hacer referencia a un operando es indicando su dirección en memoria principal, y solamente requiere una referencia adicional a memoria para obtener el operando. Es el modo de direccionamiento común para las variables globales de los programas. La pega que tiene es que cuando se dispone de grandes espacios de direccionamiento, requiere muchos bits para indicar la dirección, como es el caso de Motorola. En el Pentium de Intel, se utiliza hasta un máximo de 32 bits para indicar la dirección del operando en memoria.

Arquitectura de Computadores

Lenguaje Máquina - 11

A Registro

Modos de Direccionamiento

INC R2 C. Op.

rrrr

....

Registros de la CPU operando

Valores temporales o muy referenciados ☺ Sin referencias a memoria ☺ Requiere pocos bits Suele haber pocos registros Arquitectura de Computadores

Lenguaje Máquina - 12

Direccionamiento a Registro Este modo es similar al direccionamiento directo, pero en este caso, el campo de dirección se refiere a uno de los registros generales del procesador. Las ventajas que tiene es que solo necesita 3 o 4 bits para indicar uno de los registros generales, y que no requiere referencias adicionales a memoria. El inconveniente es que no se suele disponer de muchos registros, aunque con el advenimiento de las máquinas RISC, la tendencia es a ir incrementando su número. Se utiliza para guardar valores temporales en la evaluación de expresiones, o para mantener en registros algunas variables que se referencian muy a menudo.

Arquitectura de Computadores

Lenguaje Máquina - 12

Indirecto

Modos de Direccionamiento

INC_IND R7 C. Op.

rrrr

....

dddddd

Memoria

operando

Registros de la CPU

Cuando no se conoce la dirección del dato en tiempo de compilación Requiere múltiples accesos Arquitectura de Computadores

Lenguaje Máquina - 13

Direccionamiento Indirecto Si en el direccionamiento directo, el campo de operando indicaba la dirección del dato, en el direccionamiento indirecto, se hace referencia a una palabra de memoria principal en la que se encuentra la dirección del operando. La otra posibilidad de este direccionamiento es que el campo de operando hace referencia a un registro general en el que se encuentra la dirección del dato. Como se puede apreciar, según este esquema, con una “indirección” se requieren dos accesos adicionales a memoria para obtener el operando (si es vía registro, solo uno). Este direccionamiento se utiliza cuando la dirección de las variables no se conoce en tiempo de compilación, sino que es durante la ejecución del programa cuando se calcula la dirección del operando y se guarda ésta en memoria o en un registro. Los procesadores de Intel de la familia 80x86 y Pentium disponen de direccionamiento indirecto por registro, pero no a través de memoria. Igual le sucede al MC68000 de Motorola. Su hermano mayor, el MC68020 también dispone de direccionamiento indirecto vía memoria. Una rara variante de este modo es el direccionamiento indirecto multinivel. En este caso, el primer bit de la palabra direccionada indica si dicha palabra es ya la dirección efectiva del operando, o se debe aplicar un nuevo nivel de indirección. Supongamos que en una determinada máquina se dispone de dos operaciones para incrementar el valor de una variable en memoria principal, una por direccionamiento directo, y otra por direccionamiento indirecto por memoria, es decir, que ambas instrucciones constan de código de operación y de una dirección de memoria principal. ¿Cómo saber cuándo se está utilizando la del direccionamiento directo o la del direccionamiento indirecto? Hay dos maneras para diferenciarlas: 1) Teniendo códigos de operación distintos, que implícitamente indican el modo de direccionamiento. 2) Teniendo ambas el mismo código de operación, pero disponiendo en la instrucción de un campo que indica explícitamente el modo de direccionamiento de cada operando. ¡Ojo! Dos instrucciones en ensamblador con el mismo nombre nemotécnico pueden generar instrucciones máquina con distintos códigos de operación. Y al contrario, dos instrucciones en ensamblador con distinto nombre nemotécnico pueden generar instrucciones máquina con el mismo código de operación y distintos modos de direccionamiento.

Arquitectura de Computadores

Lenguaje Máquina - 13

Por Desplazamiento

Modos de Direccionamiento

C. Op.

rrrr

dddddddddd MEMORIA

bbbbbb

+

operando

REGISTROS

Según rrrr

 Relativo → CP Para control de bucles  Por Registro Base → Un Registro base Para áreas de datos reubicables  Indexado → Reg. de Índice Para acceso a tablas

Arquitectura de Computadores

Lenguaje Máquina - 14

Direccionamiento por Desplazamiento Hay unos cuantos métodos de direccionamiento que para formar la dirección del operando utilizan el contenido de un registro más un desplazamiento que viene explícitamente en el campo de operando. A este mecanismo para formar la dirección del operando se le conoce también como base+desplazamiento. La base está contenida en un registro, y el desplazamiento viene indicado por los bits del campo de operando. En algunos casos, el registro base utilizado puede estar implícitamente impuesto por el código de operación. Dependiendo del registro base utilizado, se distinguen los siguientes modos de direccionamiento por desplazamiento: - Relativos. En este modo se utiliza el Contador de Programa, de tal modo que la dirección efectiva se calcula añadiendo el desplazamiento que figura en el campo de operando más el contenido del Contador de Programa. Este direccionamiento lo utilizan los compiladores para indicar las direcciones de salto en las instrucciones de control de bucles. - Por registro base. Este modo de direccionamiento se utiliza comúnmente en los programas reubicables. El registro base contiene la dirección de una gran área de datos o de instrucciones. Y los bits del campo de operando indican el desplazamiento del dato a partir del comienzo del área de datos indicado por el registro base. Además de permitir programas reubicables, constituye una buena alternativa al direccionamiento directo, pues requiere pocos bits en el campo de operando. - Indexado. El propósito de este modo de direccionamiento es facilitar el acceso iterativo a las matrices o tablas de datos. Lo que se hace es indicar en los bits del campo de operando la dirección inicial de la tabla, y a esta dirección se le añade el contenido de un registro llamado “registro de índice”. Para ir referenciando los sucesivos elementos de la tabla simplemente hay que ir incrementando el contenido del registro de índice.

Arquitectura de Computadores

Lenguaje Máquina - 14

A Pila

Modos de Direccionamiento

Último en entrar

Direccionamiento

Primero en salir

44

Cima (PP)

55 44

Cima (PP)

66 55

- Implícito (PP) - Explícito

Cima (PP)

66 55

44

44

33

33

33

22

22

22

22

11

11

11

11

MEMORIA PRINCIPAL

Push 55

Push 66

Pop

33 Base

Arquitectura de Computadores

Cima (PP) 66 Ac

Lenguaje Máquina - 15

Direccionamiento a Pila La Pila es una estructura de datos que se mantiene en memoria principal. Básicamente es un vector de celdas de datos de direcciones secuenciales, en los que se meten y sacan datos con política LIFO (Last In, First Out), es decir, el último en entrar es el primero en salir. Esta estructura es muy útil como ayuda en la ejecución de los programas, pues se utiliza para guardar en ella variables temporales, parámetros, direcciones de retorno en la llamada a procedimientos, etc. El primer elemento que se mete en la pila se dice que esta en el fondo de la pila, y el último que se ha metido está en la cima de la pila. El interés de la cima de la pila es que siempre está en ella el primer dato disponible de la pila. Las operaciones con la pila son meter y sacar datos de ella, y operan utilizando un registro denominado puntero de pila que siempre contiene la dirección de la cima de la pila. En algunos procesadores, como el 68000, el registro de puntero de pila es simplemente uno de los registros generales que se utilizan para direcciones, y se accede a la pila mediante instrucciones de movimiento de datos y el ya comentado direccionamiento indirecto por registro. Los procesadores de Intel disponen de un registro específico: el Puntero de Pila, que siempre está apuntando a la cima de la pila, y se ofrecen instrucciones específicas para meter y sacar datos de la pila (PUSH y POP) en las que ni siquiera se indica explícitamente el registro de indirección, pues está implícito por el código de operación. Tanto en Motorola como en Intel, la Pila es una estructura de datos que, en contra de la intuición, crece de las direcciones altas hacia las bajas, es decir, que la cima de la Pila siempre está en una dirección más baja que la base de la Pila (salvo cuando la Pila está vacía, claro).

Arquitectura de Computadores

Lenguaje Máquina - 15

Ejemplo - Resumen

Modos de Direccionamiento

Modo Inmediato

#1234

Directo a registro

R0

Absoluto

1132

Indirecto por registro

(R2)

Indirecto por memoria

R0

1234

R1

130

R2

1132

R3

1132

(6003)

R4

-6

Indexado

1138(R4)

R5

1133

Pre-decremento

-(R5)

R6

1100

Post-incremento

(R3)+

R7

32

Reg. base + desplazamiento

32(R6)

Relativo al PC

130(PC)

PC

1002

Relativo al PC indexado

(PC,R1)

Arquitectura de Computadores

1130 1132

1234 ... ...

6000

1130

6003

1132

Memoria Principal

Lenguaje Máquina - 16

En la transparencia se muestra la especificación de un operando con valor 1234 situado en la propia instrucción (con direccionamiento inmediato), en el registro R0 (accesible mediante direccionamiento directo a registro) y en la dirección de memoria principal 1132 (accesible mediante direccionamiento directo a memoria o absoluto). Como se puede comprobar con este ejemplo, también hay otros variados modos de direccionamiento a través de los cuales se obtiene el valor 1234 del operando. Se puede acceder a este operando mediante direccionamiento indirecto a través del registro R2, o de la dirección de memoria 6003. Mediante direccionamiento indexado se obtiene igualmente la dirección del operando añadiendo el desplazamiento 1138 al contenido del registro R4. De forma similar se obtiene la dirección con el modo de registro base más desplazamiento. El direccionamiento relativo al PC también es similar al indexado o indirecto con desplazamiento, salvo que el registro utilizado es el PC. En la variante indexada, la dirección del operando se obtiene sumando el contenido del PC más el registro de índice R1. Para la gestión de la pila, los procesadores suelen ofrecer o bien instrucciones específicas (como push y pop) o bien direccionamientos apropiados, como es el caso del Motorola 68000, mediante los modos con pre-incremento y post-decremento. Con instrucciones de movimiento o copia de datos y estos direccionamientos se emula el comportamiento de las instrucciones push y pop. Consúltense los direccionamientos del Motorola 68000 para ver cómo funcionan estos direccionamientos con pre-decremento y post-incremento.

Arquitectura de Computadores

Lenguaje Máquina - 16

Instrucciones Típicas

Lenguaje Máquina

 Transferencia de Datos  Aritméticas

Ejecución de la Instrucción Operandos

 Lógicas  Transferencia de Control  Control del Sistema

ALU

Registro de Estado

Resultado

Ortogonalidad

Arquitectura de Computadores

0, 1, 2, n Operandos En Registros En Memoria

Longitud de Instrucción Lenguaje Máquina - 17

Aunque el número de instrucciones que se ofrece varía de máquina a máquina, en todas ellas suelen encontrarse los mismos tipos de instrucciones: • Transferencia de datos • Aritméticas • Lógicas • Transferencia de Control • Control del sistema Muchas de estas instrucciones utilizan dos operandos, y dependiendo de la versatilidad u ortogonalidad de la máquina, pueden permitir que ambos operandos estén solamente en registros generales, uno en registro y el otro en memoria, o los dos en memoria. Obviamente, siempre hay un compromiso entre la máxima ortogonalidad (cualquier mezcla de modos de direccionamiento), con la correspondiente longitud de instrucción que ello conlleva. En general, Intel y PowerPC suelen ofrecer instrucciones en las que no permiten todos los tipos de direccionamiento en una misma instrucción (por ejemplo, direccionamiento directo para ambos operandos), sobre todo en el caso del PowerPC, que es un procesador RISC. En cambio Motorola ofrece un juego de instrucciones más ortogonal, claro está, a cambio de tener instrucciones de hasta 10 bytes de longitud. Otra cuestión que se debe tener en cuenta es que una gran parte de las instrucciones modifican o establecen los flags de estado del Registro de Estado, indicando si la última operación ha producido overflow, si un resultado es cero, positivo o negativo, etc.

Arquitectura de Computadores

Lenguaje Máquina - 17

Transferencia de Datos (Copia)

Instrucciones Típicas

MOVE

OP_fuente,OP_destino

Op_destino := Op_fuente Operandos en:

• Registro • Memoria • Pila • Inmediato

Cargar:

Memoria → Registro

Almacenar: Registro → Memoria Arquitectura de Computadores

Lenguaje Máquina - 18

Transferencia de Datos En realidad no son instrucciones de transferencia o movimiento de datos, sino simplemente de copia. Es uno de los tipos de instrucciones más fundamentales. Estas instrucciones tienen dos operandos, el fuente y el destino, y deben copiar el contenido del operando fuente al de destino. Por tanto, deben indicar la ubicación o dirección de ambos operandos, que pueden estar en un registro, en memoria o en la pila. (El operando fuente también puede ser un operando inmediato incluido en la propia instrucción). A las instrucciones de copia de memoria a registro se las suele llamar “de carga”, mientras que las que copian de registro a memoria se denominan “de almacenamiento”.

Arquitectura de Computadores

Lenguaje Máquina - 18

Aritméticas

Instrucciones Típicas

ADD

OP_1,OP_2

Op_1 := Op_1 + Op_2

Suma, Resta, Multiplicación, División Inc, Dec, Abs, Not

Arquitectura de Computadores

- Coma Fija y Flotante - Truncamientos - Redondeos

Lenguaje Máquina - 19

Aritméticas Todos los procesadores de propósito general proporcionan las operaciones básicas aritméticas de suma, resta, multiplicación y división, siempre, al menos, para números enteros de coma fija. Los procesadores de los últimos años también suelen incluir operaciones en coma flotante, y los mainframes también manejan números decimales empaquetados. Las instrucciones aritméticas suelen ofrecerse con distintas precisiones, y no debe olvidarse que pueden producirse resultados con truncamiento o redondeo. Otras instrucciones aritméticas comunes son: incrementar, decrementar, valor absoluto y valor negado.

Arquitectura de Computadores

Lenguaje Máquina - 19

Lógicas

Instrucciones Típicas

OR

OP_1,OP_2

Op_1 := Op_1 OR Op_2

Op. Booleanas: OR, AND, XOR, NOT Manejo de bits Transformación de formato

Arquitectura de Computadores

Lenguaje Máquina - 20

Lógicas También es normal ofrecer instrucciones para manejar los bits individuales de un byte o de una palabra. Normalmente lo que hacen es realizar operaciones booleanas sobre bits, por lo que las instrucciones ofrecidas suelen ser: OR, AND, OR exclusivo y NOT (negación). Estas operaciones se aplican a bits individuales o a series de bits, de tal forma que si cada operando es una serie de bits, la operación lógica se realiza entre el primer bit de la serie 1 y el primer bit de la serie 2, entre el segundo bit de la serie 1 y el segundo bit de la serie 2, ... Algunos autores incluyen dentro de las operaciones lógicas las operaciones de Transformaciones de Formato, es decir, los desplazamientos y las rotaciones. Veámoslas en la siguiente transparencia.

Arquitectura de Computadores

Lenguaje Máquina - 20

Desplazamientos y Rotaciones

Instrucciones Típicas

A Derechas

A Izquierdas

Desp. Lógico 0

C

C

0

C

C

0

C

C

Desp. Aritmético S

Rotación

Arquitectura de Computadores

Lenguaje Máquina - 21

Desplazamientos y Rotaciones Los desplazamientos y las rotaciones se aplican sobre un único operando, y pueden actuar a derechas o a izquierdas. Los desplazamientos pueden ser lógicos o aritméticos. El desplazamiento aritmético a la derecha va replicando el bit de signo (el del extremo izquierdo) a medida que se va desplazando, por lo que se mantiene el signo en el resultado. En el desplazamiento aritmético a izquierdas, el desplazamiento no afecta al bit de signo, por lo que también se mantiene el signo en el resultado. Como ya es sabido, el efecto aritmético de un desplazamiento a izquierdas es el de ir multiplicando por las sucesivas potencias de 2, mientras que el desplazamiento aritmético a la derecha produce la división por las sucesivas potencias de 2. Ya que las rotaciones y los desplazamientos suelen afectar al bit de acarreo, estas instrucciones sirven para analizar de forma individual los bits que componen un byte o una palabra de datos, pues simplemente hay que consultar en cada momento el bit de acarreo para saber el valor que tenía el último bit de la izquierda o la derecha antes de realizar la operación.

Arquitectura de Computadores

Lenguaje Máquina - 21

Instrucciones Típicas

Control del Sistema

 Establecer Privilegio  Modificación del Registro de Estado  RESET, HALT, ...

Arquitectura de Computadores

Lenguaje Máquina - 22

Control del Sistema Estas instrucciones no afectan a operandos de los programas de usuario, sino que tienen que ver con el modo de ejecución del procesador, tales como el nivel de privilegio de ejecución (usuario, supervisor), modificación del registro de estado, RESET, HALT, y otras que varían de unas máquinas a otras. Suelen ser instrucciones reservadas para los sistemas operativos, que solamente pueden ejecutarse cuando el procesador está en modo “supervisor”.

Arquitectura de Computadores

Lenguaje Máquina - 22

Transferencia de Control

Instrucciones Típicas

A veces hay que romper el flujo secuencial de las instrucciones

Bifurcaciones If … Then Else

Control de Bucles

Saltos

Incondicionales JMP dirección

ADD OP1,OP2 CMP OP1, OP2

Arquitectura de Computadores

Interrupciones Excepciones

Condicionales

1º Establecer Estado (V,C,N,Z)

TEST OP1

Llamadas a Procedimientos

BEQ 2º BNE Bifurcar según Condición BHI

dirección

BLT

dirección

BCS

dirección

BVS

dirección

dirección dirección

Lenguaje Máquina - 23

Transferencia de control Ya sabemos que el flujo natural de ejecución de las instrucciones es el orden lineal: se ejecuta la instrucción de la siguiente dirección de memoria. No obstante, los programas tienen que modificar esa secuencialidad dependiendo de ciertas situaciones o de los datos de entrada. También se hace necesaria la ruptura del flujo secuencial de control cuando se realizan llamadas a procedimientos, que si bien mantienen una secuencialidad lógica, requieren un salto a una instrucción distinta de la siguiente en secuencia. Por esto se hace necesaria la presencia de instrucciones que permiten variar el flujo de control, lo cual se realiza con instrucciones de salto o bifurcación. Hay instrucciones de salto incondicional, que simplemente tienen un código de operación y un operando que indica la dirección de la siguiente instrucción a ejecutar. Pero en muchas ocasiones, los saltos se realizan solamente si se da una determinada circunstancia, es decir, necesitamos saltos condicionales. Los saltos condicionales se realizan en función de los bits o flags de estado del registro de estado. Estos bits los establecen muchas operaciones de transferencia de datos, lógicas y aritméticas. Además se dispone también de operaciones de comparación, que toman dos operandos y establecen los bits de estado dependiendo de la comparación de los dos operandos. También hay instrucciones de prueba o test, que establecen los flags de estado considerando solamente el valor de un único operando (positivo, negativo, cero). Algunos de los flags más comunes que suele tener el registro de estado son los que indican: overflow, acarreo, cero, negativo. Como resumen, decir que los saltos condicionales están formados por pares de instrucciones, una que establece el estado, y otra que establece la condición y el salto; si el estado cumple la condición, se produce el salto. Las instrucciones más habituales para establecer el estado son las aritméticas, las de comparación y las de prueba o test. Hay otros mecanismos para romper el flujo secuencial de ejecución, como son las corrutinas, las interrupciones y las excepciones (o interrupciones software). De éstas, en esta asignatura vamos a tratar solamente las interrupciones, pero lo haremos en el capítulo dedicado a los Sistemas de Entrada/Salida

Arquitectura de Computadores

Lenguaje Máquina - 23

…Transferencia de Control

Instrucciones Típicas

EJEMPLO

Programa que resta el valor 5 a los contenidos de las posiciones de memoria comprendidas entre la $0100 y la $0200.

Dir.

Instrucción

$5000

MOVE #$0100,R2 R2 Apunta a la 1ª dir.

$5004

SUB #5,(R2)

Resta 5 a la pos. de memoria

. . .

ADD #1,R2

Incrementa puntero

. . .

CMP #0201,R2

¿R2 en la última dirección?

. . .

BNE $5004

Si no era la última, repite

Arquitectura de Computadores

Lenguaje Máquina - 24

En el fragmento de programa de arriba se muestra un ejemplo en el que se utilizan instrucciones de bifurcación condicional para controlar la repetición del bucle en el que se van incrementando las posiciones de memoria entre la dirección $100 y la dirección $200.

Arquitectura de Computadores

Lenguaje Máquina - 24

…Llamadas a Procedimientos

Instrucciones Típicas

P. Pr. Proc 1 Llamada del p.p.

Proc 2 L CAL

Dir . 4000

RE TU RN

Call P1

CA LL

4100 4101

Programa principal

4500

Proc. P2 4800

4600 Call P2 4601

Return

4650 Call P2 4651 Return

RN U T RE 4601

Retorno al p.p. Pila inicial Arquitectura de Computadores

Proc. P1

4651

4101

4101

4101

4101

4101

Después Call P1

Después Call P2

Después Return a P1

Después Call P2

Después Return a P1

Después Return a P.P.

Lenguaje Máquina - 25

Los procedimientos se utilizan asiduamente en los lenguajes de alto nivel, por lo que el lenguaje máquina debe proporcionar un soporte para que se ejecuten eficazmente. Así, veremos aquí el mecanismo que generalmente se utiliza para realizar las llamadas a procedimientos con el nivel que ofrece el lenguaje máquina. Sabemos que un procedimiento o subrutina es un grupo de instrucciones que realizan alguna tarea y que puede ser llamado desde diversos puntos de un programa. A diferencia de los saltos, estas llamadas tienen la particularidad de que una vez terminado el trabajo del procedimiento, se devuelve el control a la siguiente instrucción del punto de llamada. Por esto, una de las primeras cosas que hay que hacer en una llamada a procedimiento es guardar la dirección de retorno en alguna parte. Veamos algunas posibilidades. En un registro. Cuando se llama a un procedimiento se guarda siempre la dirección de retorno en un registro preestablecido, así cuando finaliza el procedimiento simplemente hay que tomar la dirección de retorno de ese registro. La pega que tiene es que si desde un programa principal se llama a un procedimiento P_1, y éste llama a su vez al procedimiento P_2, al realizar la segunda llamada se machaca la dirección de retorno de la primera llamada. Este problema se produce porque se utiliza el mismo lugar para guardar la dirección de retorno de todos los procedimientos. Por esto, una mejora podría consistir en guardar la dirección de retorno en una posición de memoria al comienzo de cada procedimiento, de tal manera que si el programa principal llama al procedimiento P_1, se guarda la dirección de retorno en una zona de datos al comienzo del procedimiento P_1, y cuando éste llama al procedimiento P_2, esta dirección de retorno se guarda en la zona correspondiente del procedimiento P_2, con lo que no se machaca la primera dirección de retorno. El problema está en que no permite los procedimientos recursivos ni los reentrantes. (Un procedimiento es reentrante si en un momento dado puede tener activas varias instancias por haber sido llamado desde distintos procedimientos de distintos procesos). El mejor lugar para guardar la dirección de vuelta es la Pila. Cuando se llama a un procedimiento se mete la dirección de retorno en la cima de la pila. (Téngase en cuenta que cada proceso tiene su propia pila de trabajo). Así, si un procedimiento se llama recursivamente, se van guardando sus direcciones de vuelta en la pila, que simplemente va creciendo a medida que se producen las llamadas, y empezará a decrecer según se vaya llegando al final de cada instanciación. Por esto, todos los procesadores de propósito general disponen de instrucciones de llamada a procedimiento (CALL) que tienen un único parámetro, la dirección del procedimiento llamado, que automáticamente salva el CP en la pila antes de saltar al procedimiento llamado. Obviamente, también disponen de una instrucción de fin de procedimiento (RETURN) que saca el valor de la cima de la pila y lo pone en el CP (Contador de Programa).

Arquitectura de Computadores

Lenguaje Máquina - 25

…Llamadas a Procedimientos

Instrucciones Típicas

procedure Ejemplo (x, y: integer) is a, b: integer; begin ... b := (x * x) - (y * y); ... end Ejemplo; 0000

¡ Qué pasa con los parámetros ?

Dir. Ret.

PP

y

Direcciones

x

x ≡ (PP+2)

...

y ≡ (PP+1)

...

FFFF Arquitectura de Computadores

Pila Lenguaje Máquina - 26

Una vez que sabemos guardar la dirección de retorno, debemos ocuparnos del paso de parámetros. Podríamos pensar en poner los parámetros en una dirección fija de memoria o en registros, pero nos encontraríamos con los mismos problemas que para salvar la dirección de retorno. Por esto, los parámetros también se van a poner en la pila. Supongamos un programa que en un punto determinado realiza la siguiente llamada al procedimiento P1: CALL P_1 (x, y). Esta es la secuencia de acciones que deben llevarse a cabo para realizar la llamada a un procedimiento: 1. Meter en la pila el parámetro x. 2. Meter en la pila el parámetro y. 3. Meter en la pila el valor del CP. 4. Saltar a la dirección del procedimiento P1. Una vez que toma control el procedimiento llamado, tiene en la cima de la pila la dirección de retorno, inmediatamente debajo el parámetro y y, por último, el parámetro x. Sabiendo esto, se puede acceder a los parámetros mediante un direccionamiento relativo al PP (Puntero de Pila): PP+1, PP+2, ... Cuando en el procedimiento llamado se alcance la instrucción RETURN, su ejecución provocará el sacar de la pila la dirección de retorno y ponerla en el CP, con lo que se devolverá el control al procedimiento llamante. En éste, se deberá restaurar el estado de la pila a la misma situación que tenía antes de la llamada al procedimiento, es decir, habrá que sacar de la pila los dos parámetros que se encuentran situados en las dos posiciones más altas de la pila. Una vez que se haya dejado la pila en su situación original se continúa con la ejecución de la siguiente instrucción a la de la llamada al procedimiento. Esto funciona “aparentemente”, aunque, como veremos más adelante, hay situaciones en las que este mecanismo no es válido y necesita algún arreglo.

Arquitectura de Computadores

Lenguaje Máquina - 26

…Llamadas a Procedimientos

Instrucciones Típicas

¡ ... y las variables locales ? 0000 b a

x ≡ (PP+4)

Dir. Ret.

y ≡ (PP+3)

y x ...

FFFF Direcciones

Arquitectura de Computadores

PP

a ≡ (PP+1) b ≡ (PP)

...

Pila

Lenguaje Máquina - 27

El último aspecto que nos queda por ver de la llamada a procedimientos es la asignación de espacio para las variables locales. Las variables globales de un programa pueden guardarse o ubicarse en alguna zona fija de memoria, sin embargo, no puede hacerse lo mismo con las variables locales de un procedimiento, pues como ya hemos visto antes, se machacarían estos valores en procedimientos reentrantes o recursivos. Por lo tanto, las variables locales de un procedimiento deben guardarse también en la pila. Hasta ahora hemos visto que la llamada a un procedimiento deja en la pila los parámetros y la dirección de retorno antes de ceder el control al procedimiento llamado. Ahora, una vez que toma control el procedimiento debe ocuparse de asignar espacio para sus variables locales. Si cada variable necesita una palabra de memoria, lo que se puede hacer es dejar tantos huecos en la pila como variables haya, haciendo corresponder cada hueco a una variable. En este momento, después de haber reservado espacio para las variables locales, el escenario de la pila será el siguiente: el PP estará apuntando a la última de las variables locales, seguida del resto de las variables locales, en orden inverso al de su declaración. En nuestro ejemplo, el PP estará apuntando a la variable b y PP+1 estará apuntando a la variable a; PP+2 apuntará a la dirección de retorno, mientras que PP+3 apuntará al parámetro y y PP+4 al parámetro x. El conjunto de valores constituido por los parámetros, la dirección de retorno y las variables locales se denomina trama de pila.

Arquitectura de Computadores

Lenguaje Máquina - 27

…Llamadas a Procedimientos

Instrucciones Típicas

¡ ... y las variables temporales ? y*y

0000

PP

x*x b

x ≡ (BL+2)

a

y ≡ (BL+1)

Dir. Ret.

BL

y

a ≡ (BL-1)

x

b ≡ (BL-2)

...

FFFF Direcciones

Arquitectura de Computadores

...

Pila Lenguaje Máquina - 28

Acabamos de ver el mecanismo para referenciar las variables locales de cada rutina. No obstante, todavía se pueden presentar problemas. Por ejemplo, supongamos una llamada al procedimiento de la transparencia, en el que se debe calcular la siguiente expresión b:=(x * x)-(y * y) Es común que la evaluación de esta expresión se realice por partes, de tal manera que primero se calcula el valor de x2 y se guarda en la pila, a continuación se calcula el valor de y2 y también se guarda en la pila. Por último se toman los dos valores de la cima de la pila y se restan. Pues bien, cuando se ha metido en la pila el valor de x2 y vamos a acceder al parámetro y ¡resulta que ya no está en PP+3! Esto es porque la pila ha crecido, la cima de la pila se ha desplazado y por lo tanto el registro PP ha variado su valor. Para evitar este problema lo que se necesita es un registro que esté continuamente apuntando a la trama de la pila en curso (puede haber otras tramas debajo si hay llamadas anidadas). A este registro lo vamos a llamar BL (Base Local). Así, lo primero que debe hacer el procedimiento llamado es poner el BL con el valor de PP actual y después reservar el espacio para sus variables locales. Así, posteriormente podrá direccionar los parámetros y las variables locales mediante direccionamiento relativo al BL (BL-1, BL-2, ...), con lo que ya no importa que el PP varíe su valor debido a variables temporales.

Arquitectura de Computadores

Lenguaje Máquina - 28

…Llamadas a Procedimientos

Instrucciones Típicas

¡ ... y que pasa con el BL de las tramas anteriores ? b

0000

PP

a BL de P2

BL (de P3)

Dir. Ret.

y ≡ (BL+2)

y x

a ≡ (BL-1)

...

b ≡ (BL-2)

...

FFFF Direcciones

x ≡ (BL+3)

q BL de P1 Dir. Ret. p

¡

… y permite acceder a las variables locales de las rutinas llamantes

!

...

Arquitectura de Computadores

Lenguaje Máquina - 29

Todavía nos queda un problema por resolver. Supongamos que desde un procedimiento P1 se llama a un procedimiento P2, y que éste llama a su vez al procedimiento P3. Mientras se está ejecutando P2, el registro BL está apuntando a la trama de pila de P2, pero cuando éste llama a P3 el BL se actualiza con la dirección de la trama de pila de P3, machacando ¡y perdiendo! la dirección de la trama de pila de P2. Es decir, cuando se llama a un procedimiento se pierde la dirección de la trama de pila del procedimiento llamante. La forma de solucionar esto es muy simple, consiste en guardar en cada trama de pila la dirección de la trama de pila del proceso llamante antes de actualizar el BL con la dirección de la nueva trama de pila. Veamos cual sería el orden completo de las acciones de una llamada: • Secuencia de llamada (en el procedimiento llamante): 1. Meter los parámetros en la pila. 2. Meter en la pila la dirección de retorno. 3. Ceder el control al procedimiento llamado. • Prólogo del procedimiento llamado: 4. Guardar en la pila el valor del registro BL. 5. Copiar el registro PP al registro BL. 6. Asignar espacio en la pila para las variables locales (moviendo el PP). Por su parte, esto es lo que origina la terminación de un procedimiento: • Epílogo de la rutina llamada: 1. Liberar el espacio de las variables locales: BL → PP 2. Restaurar el anterior BL, sacándolo de la pila. 3. Retorno al procedimiento llamante, sacando la dirección de retorno de la pila. • Secuencia de retorno del procedimiento llamante: 4. Liberar el espacio de pila utilizado para los parámetros (moviendo el PP). Los procesadores suelen ofrecer instrucciones para ejecutar fácilmente el prólogo y el epílogo de los procedimientos (Intel: ENTER y LEAVE; Motorola: LINK y UNLK). Las máquinas RISC como PowerPC no disponen de este tipo de instrucciones. La instrucción ENTER del Pentium consume 11 ciclos de reloj para su ejecución, aunque si el prólogo se realiza a base de instrucciones elementales requiere solamente 1,5 ciclos ¡!

Arquitectura de Computadores

Lenguaje Máquina - 29

…Instrucciones Típicas

Lenguaje Máquina

¡ Y la Entrada/Salida ? ¿Cómo se leen y escriben los datos?

Arquitectura de Computadores

Lenguaje Máquina - 30

¡Y cómo se realiza la entrada/salida? Por supuesto que faltan los mecanismos de E/S, pero es que sobre esto hay mucho que hablar, y lo veremos con detalle en el capítulo dedicado a los Sistemas de Entrada/Salida.

Arquitectura de Computadores

Lenguaje Máquina - 30

Get in touch

Social

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