tp5.pdf
TRANSCRIPT
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).
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
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
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.
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
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é.
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
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}
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