TP5.pdf

9
INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013 ARQUITECTURA DE COMPUTADORAS Ing. Juan Carlos Ansaldi 1 Trabajo Práctico Nº 5 Procedimientos - Pila Introducción Los procedimientos son básicamente una lista de instrucciones que se pueden ejecutar desde muchos lugares diferentes de un programa, en lugar de tener que repetir la misma lista de instrucciones cada vez que se necesitan. Los procedimientos se llaman por medio de la instrucción CALL y los abandonamos (mejor dicho salimos de un procedimiento) por medio de la instrucción RET. “Deseamos (tantas cosas) escribir 4 caracteres distintos comenzando por la A y terminando por la D. Por que nos gusta hacer las cosas difíciles lo haremos en Assembler, utilizando el Debug, (No es más fácil hacerlo en el Word?. Seguro que sí, pero si lo hacemos en el Word, como hace el profesor para explicar que es una pila?, Cómo funcionan los registros SP y SS?, que significa push y pop, etc.,etc.).” Escribamos las siguientes instrucciones, utilizando el comando A del Debug, respetando las direcciones que aparecen a la izquierda. 0100 MOV DL,41 0102 MOV CX,0004 0105 CALL 0200 0108 LOOP 0105 010A INT 20 0200 MOV AH,02 0202 INT 21 0204 INC DL 0206 RET Ejecutemos nuestro programa con T, y completemos la tabla (de la cual solamente se adjunta la cabecera) teniendo en cuenta de proceder de la siguiente manera: 1) Escribir los valores de los registros correspondientes por cada “rastreo” T. 2) Cada vez que se ejecute una instrucción Call o Ret indicarlo con una cruz en la columna que corresponde. 3) La última columna la dejaremos para llenarla más adelante, por lo que debemos grabar nuestro programa (para refrescar como hacerlo veamos el TP Nº 4). IP DL CALL 0200 RET SP Valor en la Pila 1) En base a lo anterior, ¿qué acciones realizan las instrucciones CALL y RET? 2) ¿Qué acción realiza la instrucción INC sobre el registro DL? Pila y Direcciones de Retorno “Cuando voy a Bs. As, a pesar de ir casi siempre al mismo Hotel, cuando salgo llevo en mi bolsillo una tarjeta con la dirección del Hotel, porque sino no sé dónde volver (tengo muy mala memor ia)” La instrucción CALL, necesita guardar en algún lado la dirección de retorno, para saber donde debemos volver al ejecutar la instrucción RET. Para esto tenemos una porción de memoria conocida como “PILA” (stack).

Transcript of TP5.pdf

Page 1: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 1

Trabajo Práctico Nº 5 Procedimientos - Pila

Introducción

Los procedimientos son básicamente una lista de instrucciones que se pueden ejecutar desde

muchos lugares diferentes de un programa, en lugar de tener que repetir la misma lista de

instrucciones cada vez que se necesitan.

Los procedimientos se llaman por medio de la instrucción CALL y los abandonamos (mejor dicho

salimos de un procedimiento) por medio de la instrucción RET.

“Deseamos (tantas cosas) escribir 4 caracteres distintos comenzando por la A y terminando por la

D. Por que nos gusta hacer las cosas difíciles lo haremos en Assembler, utilizando el Debug, (No

es más fácil hacerlo en el Word?. Seguro que sí, pero si lo hacemos en el Word, como hace el

profesor para explicar que es una pila?, Cómo funcionan los registros SP y SS?, que significa push

y pop, etc.,etc.).”

Escribamos las siguientes instrucciones, utilizando el comando A del Debug, respetando las

direcciones que aparecen a la izquierda.

0100 MOV DL,41 0102 MOV CX,0004 0105 CALL 0200 0108 LOOP 0105 010A INT 20

0200 MOV AH,02 0202 INT 21 0204 INC DL 0206 RET

Ejecutemos nuestro programa con T, y completemos la tabla (de la cual solamente se adjunta la

cabecera) teniendo en cuenta de proceder de la siguiente manera:

1) Escribir los valores de los registros correspondientes por cada “rastreo” T.

2) Cada vez que se ejecute una instrucción Call o Ret indicarlo con una cruz en la columna que

corresponde.

3) La última columna la dejaremos para llenarla más adelante, por lo que debemos grabar nuestro

programa (para refrescar como hacerlo veamos el TP Nº 4).

IP DL CALL 0200 RET SP Valor en la Pila

1) En base a lo anterior, ¿qué acciones realizan las instrucciones CALL y RET?

2) ¿Qué acción realiza la instrucción INC sobre el registro DL?

Pila y Direcciones de Retorno

“Cuando voy a Bs. As, a pesar de ir casi siempre al mismo Hotel, cuando salgo llevo en mi bolsillo

una tarjeta con la dirección del Hotel, porque sino no sé dónde volver (tengo muy mala memoria)”

La instrucción CALL, necesita guardar en algún lado la dirección de retorno, para saber donde

debemos volver al ejecutar la instrucción RET.

Para esto tenemos una porción de memoria conocida como “PILA” (stack).

Page 2: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 2

Veamos el siguiente ejemplo, el cual debemos “correr” con el comando T , excepto al llegar a la

INT 20, la cual ejecutamos con el comando P.

0100 CALL 0200 0103 INT 20 0200 CALL 0300 0203 RET 0300 CALL 0400 0303 RET 0400 RET

Para completar la tabla, las tres primeras columnas no tienen complicaciones, pero la última se nos

puede complicar. Teniendo en cuenta que, como dijimos anteriormente, la “pila” es una porción de

memoria:

3) ¿Cómo hacemos para “ver” los valores que se guardan en ella?

4) ¿Cómo sabemos en que dirección se encuentran los valores que vamos guardando?

Una vez que encontramos la respuesta a los interrogantes anteriores, estamos en condiciones de

llenar la tabla (también de la cual solamente se adjunta la cabecera).

IP Instrucción SP Valor en la Pila

En este programa, la instrucción que se encuentra en la dirección 100h llama a la que está en 200h,

la cual llama a la que se encuentra en 300h, que a su vez llama a la que está en 400h, donde por fin

nos encontramos con una instrucción de retorno (RET). Esta instrucción RET devuelve el control a

la instrucción que hay a continuación de la CALL, la dirección 300h, comenzando a ejecutar

instrucciones en la dirección 303h. Pero en esa dirección se encuentra otra

dirección RET, la cual envía el control a la 203h. En esta dirección se vuelve a encontrar otra

instrucción 203h, y así sucesiva mente. Cada instrucción RET saca (POP) la última dirección, es

decir, la más alta de la pila; esto quiere decir que las instrucciones RET siguen el mismo camino

que las instrucciones CALL, sólo que en dirección contraria.

5) Ahora estamos en condiciones de llenar la columna de la derecha de nuestro primer

programa, el cual “deberíamos tener grabado”.

Las instrucciones PUSH y POP

La pila es muy útil para guardar palabras de datos temporalmente, siempre y cuando tengamos

cuidado de restablecer la pila antes de una instrucción RET. Hemos visto que una instrucción

CALL empuja (PUSH) la dirección de retorno (una palabra) a la parte superior de la pila, mientras

que una instrucción RET saca (POP) esta palabra de la pila, la pone en el registro IP y saca a la

superficie (es decir, a la parte superior de la pila) la palabra que estaba justo debajo.

Con las instrucciones PUSH y POP se puede hacer más o menos lo mismo: nos permiten empujar y

sacar palabras de la pila. Pero, ¿cuándo es necesario hacer esto?

A menudo es necesario grabar los valores de algún registro al principio de un procedimiento y

recuperarlos al final, justo antes de la instrucción RET. De esta forma podemos usar estos

registros, dentro del procedimiento, de la forma que mejor nos convenga, siempre y cuando

tengamos cuidado de recuperar sus valores al final. Los programas suelen estar formados por

muchos niveles de procedimientos, donde cada nivel llama a un procedimiento y éste a otro

procedimiento de nivel inferior. Salvando los valores de los registros al principio del

Page 3: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 3

procedimiento y recuperándolos al final, se suprimen todas las interacciones no deseadas entre

procedimientos a niveles diferentes, y esto hace mucho más fácil la tarea de programar. Ahora

veamos un ejemplo que se puede usar para salvar y restablecer los valores de los registros CX y

DX:

0100 MOV CX,FFFF 0103 MOV DX,EEEE 0106 CALL 0200 0109 INT 20 ......................................... 0200 PUSH CX 0201 PUSH DX

0202 MOV CX,0003 0205 INC DL 0207 LOOP 0205 0209 POP DX 020A POP CX 020B RET

6) Ejecutar el ejemplo anterior, y completar una tabla que nos permita registrar los valores de

IP, SP y los datos guardados temporalmente en la pila, indicando en particular cuando se ha

ejecutado instrucciones PUSH, POP, CALL y RET.

Las instrucciones POP están en orden inverso a las PUSH. Esto se debe a que la instrucción POP

toma la última palabra que se ha puesto en la pila, y en este caso el valor del registro DX está

encima del valor del registro CX.

Salvando y restableciendo CX y DX podemos cambiar estos registros en el procedimiento que

comienza en la dirección 200h, pero sin cambiar los valores que usa el procedimiento que llama a

este último. Una vez salvados los registros CX y DX, éstos se pueden usar para guardar variables

“locales” (variables que podemos usar en este procedimiento sin afectar a los valores utilizados

por el programa que ha efectuado la llamada). Estas variables locales se usan para simplificar el

programa. Mientras tengamos cuidado de restablecer los valores originales, no nos tendremos que

preocupar de que los, procedimientos cambien los registros que usa el programa que efectúa la

llamada. Esto se verá más claro en el ejemplo siguiente, que es un procedimiento para leer un

número hexadecimal. Al contrario que el programa anterior, este nuevo programa sólo nos

permitirá aceptar caracteres válidos, como por ejemplo la A, pero no aceptará la K.

Leer números hexadecimales con más elegancia

Queremos crear un procedimiento que lea caracteres hasta que reciba uno que pueda convertir en

un número hexadecimal comprendido entre 0h y Fh. No queremos visualizar los caracteres

inválidos, así es que desplazaremos la entrada usando una nueva función INT 21h, la número 8, la

cual lee un carácter, pero no permite que éste pase a imprimir en la pantalla. De esta forma

podemos imprimir sólo los caracteres que son válidos.

Pongamos 08h en el registro AH (MOV AH,08) y ejecute esta instrucción, tecleando una “A”

inmediatamente después de introducir el comando G 104:

0100 MOV AH,08

0102 INT 21

7)¿Qué es lo que ocurre?

Usando esta función podemos conseguir que nuestro programa lea caracteres sin escribirlos en la

pantalla, hasta que lea un dígito hexadecimal válido (0h a 9h o Ah a Fh), el cual sí imprimirá.

Veamos el siguiente ejemplo:

0200 PUSH DX 0201 MOV AH,08 0203 INT 21 0205 CMP AL,30 0207 JB 0203 0209 CMP AL,46 020B JA 0203 020D CMP AL,39 020F JA 021B

0211 MOV AH,02 0213 MOV DL,AL 0215 INT 21 0217 SUB AL,30 0219 POP DX 021A RET 021B CMP AL,41 021D JB 0203 021F MOV AH,02

Page 4: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 4

0221 MOV DL,AL 0223 INT 21 0225 SUB AL,37

0227 POP DX 0228 RET

8) Interpretar como funciona el programa anterior, para eso nosotros les daremos una pequeña

ayuda.

Las instrucciones JA (Jump if Above, saltar si está por encima) y JB (Jump if Below, saltar si está

por debajo) tratan a los dos números como si fuesen números sin signo, mientras que la instrucción

JL que usamos anteriormente trata a ambos números como un complemento a dos.

Al llegar a la línea 21h sabemos que tenemos un dígito válido comprendido entre 0 y 9; así que

restamos el código del carácter 0 y devolvemos el resultado en el registro AL, acordándonos de

recuperar (POP) el valor del registro DX que salvamos en la pila al principio del procedimiento. El

proceso para los dígitos comprendidos entre la A y la F es muy parecido. Fíjese que en este

procedimiento tenemos dos instrucciones RET; podíamos haber tenido más, o simplemente

podíamos haber tenido una.

He aquí un programa muy simple para comprobar el procedimiento:

0100 CALL 0200 0103 INT 20

Usar el comando G con un punto de ruptura, o únicamente el comando P, puesto que lo que

queremos es ejecutar la instrucción CALL 200h sin ejecutar la INT 20h, para ver los registros justo

antes de que el programa termine y se restablezcan los registros.

9) Comprobar con este procedimiento los límites:”/” (el carácter anterior al 0), el 0, el 9, el

carácter “:" (el carácter que va después del 9), y así sucesivamente.

Ahora que ya tenemos este procedimiento, el programa para leer un número hexadecimal de dos

dígitos, con detección de errores, es bastante sencillo:

0100 CALL 0200 0103 MOV DL,AL 0105 MOV CL,04 0107 SHL DL,CL 0109 CALL 0200

010C ADD DL,AL 010E MOV AH,02 0110 INT 21 0112 INT 20

10) Grabar el programa anterior, incluyendo el procedimiento.

Este programa se puede ejecutar desde el DOS, puesto que lee un número hexadecimal de dos

dígitos y muestra en la pantalla el carácter ASCII que corresponde al número que se ha

introducido.

Aquí puede apreciarse también la razón por la cual hemos salvado el registro DX en el

procedimiento. El programa principal guarda el número hexadecimal en el registro DL, por lo que

no queremos que el procedimiento que comienza en 200h cambie el valor que hay en DL. Por otra

parte, el procedimiento tiene que usar el registro DL para imprimir los caracteres en la pantalla.

Por tanto, usando las instrucciones PUSH DX -al principio del procedimiento- y POP DX -al final-

evitamos este problema.

Page 5: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 5

Ejercicios complementarios de pila

11) ¿Cuáles son los valores que se guardan en la pila si ejecutamos el programa que se lista a

continuación a partir de la instrucción a la que apunta el contador de programa o registro de

próxima instrucción hasta que finaliza? . ¿Cuál será el nuevo valor del puntero de pila? DX= 3B87h IP=0103h SP=FFEEh BX=2345h AX=0211h R.Estado=7234h CS=1F52h CS:0100 MOV DX,AX

CS:0102 PUSH DX

CS:0103 CALL 300

CS:0106 INT 21

CS:0108 POP DX

CS:0300 MOV DH,25

CS:0302 INT 21

CS:0304 RET

12) Idem anterior con: BX= 1122h IP=0102h SP=FFAEh DX=2345h AX=0211h R.Estado=7223h CS=23F1h

CS: 0100 PUSH AX

CS: 0102 CALL 300

CS: 0104 INT 21

CS: 0106 POP DX

CS: 0108 INT 20

CS: 0300 MOV DH,20

CS: 0302 INT 21

CS: 0304 RET

13) ¿ Qué ocurrirá si ejecutamos el programa que se lista a continuación, utilizando el modelo de

memoria pequeño?. ¿Cuál será el último valor de SP si inicialmente tenía el valor SP=FFEE? CS: 0100 MOV CX,FFFE

CS: 0103 MOV AX,FFFF

CS: 0106 PUSH AX

CS: 0107 LOOP 106

CS: 0109 INT 20 Comprobar su funcionamiento con el DEBUG.

14) Idem anterior pero para el siguiente listado. CS: 0100 MOV CX,FFFE

CS: 0103 POP AX

CS: 0104 LOOP 106

CS: 0106 INT 20 Comprobar su funcionamiento con el DEBUG.

15) ¿Qué diferencia tienen los siguientes listados en assembler con respecto a los 4 valores que

toma el registro AX, si suponemos que partimos de iguales datos en la zona de la pila?

¿Cuál es el valor inicial y cuál el final del Puntero de Pila en ambos casos?. ¿A qué se debe la

diferencia?

Listado A)

CS:0100 MOV BP,SP

CS:0102 MOV AX,[BP+00]

CS:0105 MOV AX,[BP+02]

CS:0108 MOV AX,[BP+04]

CS:010B MOV AX,[BP+06]

Listado B)

CS:0100 POP AX

CS:0101 POP AX

CS:0102 POP AX

CS:0103 POP AX

Comprobar su funcionamiento con el DEBUG.

16- a. Representar los diferentes estados de la pila detallando los valores que se guardan en la

misma y los valores del puntero de pila al ejecutar paso a paso el programa que se describe a

continuación a partir de la dirección que indica el IP.

16- b. Indicar las direcciones absolutas en donde se encuentra el operando de las instrucciones que

hacen uso de la memoria principal (área de datos y pila únicamente), cuales son los datos que

contienen y de donde provienen. DS=A320 SS=7F32 SP= FFEE IP=0100 RE=7898

197D:0100 BB0220 MOV BX,2002

197D:0103 B86223 MOV AX,2362

197D:0106 BE000F OV SI,0F00

197D:0109 53 PUSH BX

197D:010A 50 PUSH AX

197D:010B 88C5 MOV CH,AL

197D:010D 882E003A MOV

[3A00],CH

197D:0111 8AA4002B MOV

AH,[SI+2B00]

197D:0115 E8F800 CALL 0210

197D:0118 B404 MOV AH,04

197D:011A CD21 INT 21

..........................................

197D:0210 50 PUSH AX

197D:0211 B224 MOV DL,24

197D:0213 B002 MOV AL,02

197D:0215 CD21 INT 21

197D:0217 C3 RET

17) Idem anterior

Page 6: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 6

CS=209A DS=5FF0 SS=60F0 SP= FFEE IP=0100 RE=7898

CS:0100 BA8509 MOV DX,0985

CS:0103 B82362 MOV AX,6223

CS:0106 BEF000 MOV DI,00F0

CS:0109 52 PUSH BX

CS:010A 50 PUSH AX

CS:010B 8861 MOV CL,AL

CS:010D 880E005B MOV [5B00],CL

CS:0111 8A95105AMOVDL,[DI+5A10]

CS:0115 E80D02 CALL 0310

CS:0118 B404 MOV AH,04

CS:011A CD21 INT 21

..........................................

CS:0310 50 PUSH AX

CS:0311 B231 MOV DL,31

CS:0313 B002 MOV AL,02

CS:0315 CD21 INT 21

CS:0317 C3 RET

18) Idem anterior:

CS= A723 DS=B520 SS=7A81 SP= E9DE IP=0100

CS:0100 BA0A00 MOV DX,000A

CS:0103 B90B04 MOV CX,040B

CS:0106 BE0005 MOV SI,0500

CS:0109 51 PUSH CX

CS:010A 52 PUSH DX

CS:010B 89D0 MOV AX,DX

CS:010D 3E8836341B MOV

DS:[1B34],DH

CS:0112 898C0005 MOV [SI+0500],CX

CS:0116 E80700 CALL 0120

CS:0119 CD20 INT 20

CS:011B

CS:0120 5B POP BX

CS:0121 58 POP AX

CS:0122 B401 MOV AH,01

CS:0124 CD21 INT 21

CS:0126 C3 RET

19.a) Dadas las siguientes direcciones absolutas en 20 bits, 18303 18304 18305 18306 26798

26799 2679A 2679B 2679C 2679D 2679E 2679F 16A70 16A71 16A72 16A73 168E3 168E4

29548 29549 2954A 2954B 2954C 2954D 2954E 2954F

determinar cuáles de ellas son utilizadas con datos por el siguiente segmento de programa, y en

caso de que así sea, cuáles son los datos que contienen y de donde provienen CS= DS=ES=SS SP= FFCE

167D:0100 MOV AX,0980

167D:0103 MOV BX,01A1

167D:0107 PUSH AX

167D:0108 PUSH BX

167D:0109 ADD AX,BX

167D:010B MOV [1B34],AX

167D:010E MOV [BX+0100],BL

167D:0112 INT 20

19.b) ¿Cuál será la dirección absoluta de la próxima instrucción a ejecutar al finalizar el programa?

20) Dado el siguiente programa en el cual SS= ED61 y SP= FFEE RE = 7211 (4.00 ptos.) 152A:0100 B92020 MOV CX,2020

152A:0103 B81001 MOV AX,0110

152A:0106 A36151 MOV [5161],AX

152A:0109 05D3F3 ADD AX,F3D3

152A:010C 50 PUSH AX

152A:010D E81001 CALL 0220

152A:0110 58 POP AX

152A:0111 CD20 INT 20

152A:0220 8B1E6151 MOV BX,[5161]

152A:0224 53 PUSH BX

152A:0225 B409 MOV AH,09

152A:0227 BA0010 MOV DX,1000

152A:022A CD21 INT 21

152A:022C C3 RET

812B:1000 4F 4A 4F 2C 20 4E 4F 20-74 65 72 6D 69 6E 61 20

812B:1010 63 6F 6E 20 65 72 72 6F-72 24 20 5B 2F 56 5D 0D

Calcular:

En que direcciones absolutas de la pila se guardan los valores al ejecutarse la INT 21 de la

dirección 152A:022A y de qué dirección absoluta obtiene la dirección de retorno al ejecutarse el

RET de la dirección 152A:022C

En que direcciones absolutas se guarda el operando de la instrucción ADD AX,F3D3

En que direcciones absolutas se guarda el valor de AX en la instrucción MOV [5161],AX

Cuál es el valor que contendrá IP al finalizar la ejecución del programa. Explique por qué.

Page 7: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 7

Complemento al Trabajo Práctico Nº 5. La pila

La pila (“stack”) es una característica interna de los microprocesadores. Proporciona a los

programas un lugar donde almacenar y seguir la pista del trabajo que se está llevando a cabo. La

función más importante de la pila es la de mantener el registro de los lugares donde se llamó a una

subrutina y de los parámetros que se le pasaron. La pila también puede utilizarse para el

almacenamiento temporal de datos de trabajo, aunque esto es menos fundamental y no tan común.

La pila obtiene su nombre por analogía con los montones de platos apilados (pilas de platos) de las

cafeterías.

Cuando un dato nuevo es introducido (push) en la cima de la pila, el anterior es extraído (pop).

Una pila siempre opera en el orden último-en-entrar-primero-en-salir (LIFO: “last-in-first-out”).

Esto significa que cuando la pila se utiliza para seguir la pista de los retornos de las subrutinas, la

primera llamada a subrutina que se hizo es la última que vuelve. De esta manera, la pila mantiene

ordenado el funcionamiento del programa, las subrutinas y las rutinas de tratamiento de

interrupción, sin importar lo complejo de la operación. En la mayoría de los microprocesadores, la

pila se utiliza desde la parte de abajo (dirección más alta) a la parte de arriba (dirección más baja)

de forma que cuando un dato es introducido (push) a la cima de la pila, se almacena en la posición

de memoria justo por debajo de la cima actual de la pila. La pila crece hacia abajo, de forma que, a

medida que se añaden datos, la posición de la cima de la pila se mueve más y más hacia

direcciones más bajas, decrementando cada vez el valor de SP. Cualquier parte de cualquier

programa puede crear un nuevo espacio de pila en cualquier momento, pero esto no se hace

normalmente. Por lo general, cuando un programa está funcionando se crea para él una sola pila y

se utiliza durante el funcionamiento del programa. No hay una forma sencilla de estimar el tamaño

de la pila que un programa pueda necesitar, y en general, el diseño del microprocesador no

proporciona ninguna manera automática de detectar cuándo el espacio de la pila está agotado o

casi agotado. Esto puede llevar a que los programadores estén indecisos acerca del espacio que

deben reservar para la pila. Una estimación conservadora del espacio que hay que reservar da

alrededor de 2 KB (2048 bytes), que es la cantidad que asignan por defecto la mayoría de los

compiladores de lenguajes de alto nivel.

En el caso de las interrupciones, antes de que se pase a ejecutar la subrutina del sistema operativo

o del BIOS que da servicio a dicha interrupción, la UC guarda automáticamente en memoria la

dirección de retorno, donde está la instrucción a partir de la cuál continua el programa

interrumpido. En este caso, la dirección de retorno es segmentada.

De esta forma, luego que se ejecutó dicha subrutina, se podrá retornar a ejecutar el programa.

Cuando se trata de Interrupciones también es normal que la UC guarde el estado actual del

Registro de Estado, que incluye, como sabemos el Indicador de Acarreo, Desbordamiento, Cero,

etc.

La pila es necesaria, porque es común que la subrutina llamada por una interrupción a su vez sea

interrumpida para llamar a otra subrutina, y esta segunda también puede sufrir interrupciones, y así

sucesivamente.

A fin de aclarar los conceptos, veamos un ejemplo realizado utilizando un microprocesador de

arquitectura 80x86 en el cual es utilizada la pila por Interrupciones y también por Procedimientos.

Sería conveniente ejecutar el siguiente ejemplo utilizando el DEBUG, y ver el volcado de memoria

de las direcciones que corresponden a la pila.

11F5:0100 MOV AH,02 11F5:0102 MOV DL,30 11F5:0104 INT 21 11F5:0106 CALL 0200 11F5:0109 INT 20

.................................. 11F5:0200 MOV AH,02 11F5:0202 MOV DL,31 11F5:0204 INT 21 11F5:0206 RET

Page 8: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 8

En la Figura (1) se supone una pila definida a partir de la

dirección de memoria FFFFh, para el programa del listado. Este

programa luego de la interrupción INT 21 debe proseguir en la

instrucción localizable mediante la dirección de retorno

11F5:0106h.

No bien la CPU acepta la solicitud de interrupción, guarda automáticamente en la pila dicha

dirección: 11F5:0106h, quedando en el orden que se muestra en la Figura (2). Sobre este valor se

guarda otro valor, indicado 3446, que debe ser el valor del Registro de Estado.

Como sabemos existe un registro “puntero de pila” ("stackpointer"-SP), que contiene la dirección

de la pila que en el al comienzo corresponde a su cima, siendo el mismo actualizado también en

forma automática por la UC cada vez que se lee o escribe la pila.

En el ejemplo, se ha supuesto que al sobrevenir la interrupción se podía apilar a partir del

comienzo de la pila (dirección FFFEh), o sea que en la pila no había nada "apilado" anteriormente.

Entones el SP en una PC estaría con el valor FFFEh antes de la interrupción, para alcanzar el valor

FFF8h luego que ella tiene lugar, indicando así el SP la nueva dirección de la cima de la pila.

Cuando se termina de ejecutar la subrutina que atiende la interrupción, se retorna al programa

interrumpido, leyendo el valor de la pila 11F5:0106h, y SP vuelve a indicar el valor FFFEh, que

era el que tenía antes de que se llamó a la interrupción, Figura (3). En la dirección 0106h, hay una

llamada a un procedimiento, por lo que nuevamente se guardará en la pila el valor de retorno

0109h, y el SP decrementará su valor a FFFCh, Figura (4). Se hace notar que en este caso se

guarda únicamente en valor de desplazamiento de la dirección de retorno y no como en el caso de

la interrupción que se guardó el valor segmentado de la dirección de retorno.

En el procedimiento hay una nueva interrupción, (INT 21) apilándose los valores como se observa

en la Figura (5).

En la Figura (6) se representa el estado de la pila después de finalizada la interrupción, y en la

Figura (7), el estado de la pila al retornar del procedimiento. Es de hacer notar que los datos en la

pila, al igual que en cualquier parte de la memoria, no se borran, sino que son sobrescritos por

datos nuevos.

Instrucciones de manejo de la pila

PUSH {registro/memoria}

Page 9: TP5.pdf

INGENIERÍA EN SISTEMAS DE INFORMACIÓN - 2013

ARQUITECTURA DE COMPUTADORAS

Ing. Juan Carlos Ansaldi 9

Guarda una palabra de un origen especificado en la pila para uso posterior. El origen puede ser un

registro general, una dirección de memoria o un registro de segmento. El SP se disminuye en 2.

POP {registro/memoria}

Saca una palabra de la pila previamente guardada y la envía a un destino especificado, que puede

ser un registro general, una dirección de memoria o un registro de segmento (salvo CS). El SP se

incrementa en 2.

PUSHA {sin operandos}

Copia los registros de uso general AX,BX,CX,DX,SI,DI,BP,SP en la pila. Para procesadores

80286 y superiores. El SP se decrementa en 16 (10h).

POPA {sin operandos}

Saca los registros de uso general AX,BX,CX,DX,SI,DI,BP,SP de la pila. Para procesadores 80286

y superiores. El SP se incrementa 16 (10h).

PUSHF {sin operandos}

Guarda en la pila el contenido del registro de estado. El SP se disminuye en 2.

POPF {sin operandos}

Saca de la pila la palabra previamente guardada y la envía al registro de estado. El SP se

incrementa en 2.

Aprovechamos la oportunidad para recordar los indicadores del registro de estado de la familia

80x86. Consideramos el registro de la figura:

// NT IOPL OF DF IF TF SF ZF // AF // PF // CF

CF: Indicador de Acarreo

PF: Indicador de Paridad

AF: Indicador Auxiliar de Acarreo

ZF: Indicador de Cero

SF: Indicador de Signo

OF: Indicador de Desbordamiento

TF: Indicador de Trampa-Tap. Pone el microprocesador en modo de paso simple y habilita la

depuración de un programa.

IF: Indicador de habilitación de Interrupciones. Habilita interrupciones externas cuando se pone

a 1 y las deshabilita cuando se pone a 0.

DF: Indicador de dirección. Con DF a cero, SI y/o DI son incrementados automáticamente, con DF

a cero, SI y/o DI son decrementados automáticamente.

IOPL y NT: se utilizan cuando el microprocesador está en modo protegido.

IOPL: Indicador de Entrada/Salida de privilegio se utiliza para garantizar que una instrucción

realiza solo aquellas operaciones que está autorizada a realizar.

NT: indicador de tartas anidadas, se utiliza para indicar si la ejecución de la tarea actual está

anidada en otra tarea. Si NT=1 la tarea actual anidada tiene un enlace válido a la tarea previa.

Luego en el ejemplo anterior, los valores que se guardaron en la pila al producirse la interrupción

21h, se pueden tranquilamente decodificar teniendo en cuenta el orden de los indicadores del

registro de estado.

3446h= 0011010001000110b

7202h= 0111001000000010b