tamaño: 175910B

Anuncio
SISTEMAS BASADOS EN MICROPROCESADORES
Grado en Ingeniería Informática
ENUNCIADO PROBLEMA 1
A continuación se incluye el código de una aplicación formada por un programa principal
escrito en lenguaje C, así como de subrutinas o funciones y de un programa residente
escritos en lenguaje ensamblador del 8086. En el código se han distribuido un conjunto de
marcadores numéricos que permiten situar al alumno en distintas zonas de dicho
programa sobre los cuáles se realizan preguntas. El programa implementa un reloj digital
que muestra la hora y los minutos en la pantalla del PC.
Programa Principal
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
extern
extern
extern
extern
extern
int far
void far
void far
void far
void far
DetectarDriver ();
DesinstalarDriver ();
ActivarReloj ();
PararReloj ();
ActualizarReloj (int hora, int minutos, int segundos);
void main()
{
char c;
int salir;
int hora, minutos, segundos; (P9)
if (DetectarDriver()==1) (P6)
{
printf(“Driver no instalado.\n”);
exit(-1);
}
salir = 0;
while( !salir )
{
c = getchar();
if (c==’a’|| c==’A’)
{
printf(“Introduzca la hora (0-23): “);
scanf(“%d”, &hora);
printf(“Introduzca los minutos (0-59): “);
scanf(“%d”, &minutos);
printf(“Introduzca los segundos (0-59): “);
scanf(“%d”, &segundos);
PararReloj();
ActualizarReloj( hora, minutos, segundos ); (P1)(P2)
ActivarReloj();
}
if (c==’s’|| c==’S’) salir = 1;
}
DesinstalarDriver();
printf(“Saliendo del programa de control del reloj.\n”);
}
Rutinas en Ensamblador
_text segment byte public ‘code’
assume cs:_text
_DetectarDriver proc far
push es
xor ax, ax
mov es, ax
cmp word ptr es:[61h*4], 0
jne _detectar_int
cmp word ptr es:[61h*4+2], 0
je _detectar_nodriver
_detectar_int:
mov ah, 00h (P6)
int 61h
cmp ax,0F0F0h
jne _detectar_nodriver
xor ax, ax
jmp _detectar_fin
_detectar_nodriver:
mov ax, 1
_detectar_fin:
pop es
ret
_DetectarDriver endp
_DesinstalarDriver proc far
mov ah, 01h
int 61h
ret
_DesinstalarDriver endp
_PararReloj proc far
mov ah, 02h
int 61h
ret
_PararReloj endp
_ActivarReloj proc far
mov ah, 03h
int 61h
ret
_ActivarReloj endp
_ActualizarReloj proc far (P1)(P2)(P3)
push bp
push bx
push cx
push dx
mov bp, sp
mov bx, bp[12] (P2)(P3)
mov cx, bp[14] (P2)(P3)
mov dx, bp[16] (P2)(P3)
mov ah, 04h (P1 <-)
int 61h
pop dx
pop cx
pop bx
pop bp
ret
_ActualizarReloj endp
public
public
public
public
public
_DetectarDriver
_DesinstalarDriver
_PararReloj
_ActivarReloj
_ActualizarReloj
_text ends
end
Driver (archivo .com)
code segment
assume cs:code
org 100h
driver_start:
jmp instalar
;Variables del driver
old_61h
dw
old_1Ch
dw
estado_reloj db
contador
dw
hora
dw
minutos
dw
segundos
dw
0, 0
0, 0
1 (P9)
0
0 (P9)
0 (P9)
0 (P9)
;Reloj del driver
reloj_driver proc far
sti
cmp estado_reloj, 1
jne reloj_driver_fin
inc contador
cmp contador, 18 (P7)
jne pintar_reloj
mov
inc
cmp
jne
contador, 0
segundos
segundos, 60
pintar_reloj
mov
inc
cmp
jne
segundos, 0
minutos
minutos, 60
pintar_reloj
mov
inc
cmp
jne
minutos, 0
hora
hora, 24
pintar_reloj
mov hora, 0
pintar_reloj:
call mostrar_reloj
reloj_driver_fin:
iret
reloj_driver endp
;Interfaz de comunicación con el driver
interfaz_driver proc far (P3)
sti
cmp ah, 00h
jne driver_desinstalar
mov ax, 0F0F0h
jmp driver_fin
driver_desinstalar:
cmp ah, 01h
jne driver_parar_reloj
call desinstalar
jmp driver_fin
driver_parar_reloj:
cmp ah, 02h
jne driver_activar_reloj
mov estado_reloj, 0
jmp driver_fin
driver_activar_reloj:
cmp ah, 03h
jne driver_actualizar_reloj
mov estado_reloj, 1
jmp driver_fin
driver_actualizar_reloj: (P3)
cmp ah, 04h
jne driver_fin
mov
mov
mov
mov
hora, XX (P4)
minutos, XX (P4)
segundos, XX (P4)
contador, 0
driver_fin:
iret
interfaz_driver endp
;Rutinas auxiliares del driver
;Rutina para mostrar el reloj por pantalla (hh:mm:ss)
mostrar_reloj proc near
.................
ret
mostrar_reloj endp
;Rutinas de instalación / desinstalación del driver
;Funcion que desinstala el driver
desinstalar proc near
push ax
push es
xor ax, ax
mov es, ax
cli
;Vector 1Ch
mov ax, old_1Ch
mov es:[1Ch*4], ax
mov ax, old_1Ch+2
mov es:[1Ch*4+2], ax
;Vector 61h
mov ax, old_61h
mov es:[61h*4], ax
mov ax, old_61h+2
mov es:[61h*4+2], ax
sti
mov es, cs:[2Ch]
mov ah, 49h
int 21h
mov
mov
mov
int
ax, cs
es, ax
ah, 49h
21h
pop es
pop ax
ret
desinstalar endp
;Funcion que instala el driver
instalar proc near
xor ax, ax
mov es, ax
cli
mov
mov
mov
mov
ax, es:[1Ch*4]
old_1Ch, ax
ax, es:[1Ch*4+2]
old_1Ch+2, ax
mov
mov
mov
mov
ax, es:[61h*4]
old_61h, ax
ax, es:[61h*4+2]
old_61h+2, ax
mov es:[1Ch*4], offset reloj_driver (P7)
mov es:[1Ch*4+2], cs
mov es:[61h*4], offset interfaz_driver
mov es:[61h*4+2], cs
sti
mov dx, offset instalar
int 27h
instalar endp
code ends
end driver_start
SISTEMAS BASADOS EN MICROPROCESADORES
Grado en Ingeniería Informática
PREGUNTAS PROBLEMA 1
P1. A la vista del código fuente y, particularmente, analizando con detalle los
fragmentos del mismo marcados con (P1), dibuje la pila del sistema cuando
el programa principal se encuentra en el punto (P1 <-). Justifique su
repuesta. (0,5 puntos)
La llamada a “ActualizarReloj” desde C apila
16 bits
sus tres parámetros en orden inverso a su
declaración, ocupando cada uno de ellos dos
segundos
BP+16
bytes. A continuación apila la dirección de
minutos
BP+14
retorno de la siguiente instrucción de CM del
hora
BP+12
programa en C (llamada a “ActivarReloj”).
CS retorno
BP+10
Como todas las rutinas de ensamblador son
IP retorno
BP+8
lejanas (far), dicha dirección de retorno consta
BP+6
BP
de dos palabras (dos bytes por palabra): el
BP+4
BX
valor del registro de segmento CS y el del
BP+2
CX
registro de offset IP, apilados en este orden.
BP+0
DX
SP = BP
Seguidamente se carga el CS y el IP con la
dirección de la primera instrucción de
“ActualizarReloj” y se inicia la ejecución de
ésta, que apila los valores de los registros de
16 bits BP, BX, CX y DX en este orden. El
puntero de pila y el registro BP quedan
apuntando al valor de DX.
P2. De acuerdo con el código fuente del programa principal y de la rutina
ActualizarReloj, especialmente las líneas marcadas con (P2), indique la
información que se almacena en cada uno de los registros de la CPU: BX,
CX, DX. Tenga en cuenta la funcionalidad de la aplicación. Justifique su
repuesta. (0.5 puntos)
Según el esquema de la pila indicado en el ejercicio anterior y los valores
almacenados en los correspondientes desplazamientos de BP, BX se carga con el
parámetro “hora”, almacenado en la dirección BP+12; CX se carga con el
parámetro “minutos”, almacenado en BP+14; DX se carga con el parámetro
“segundos”, almacenado en BP+16.
P3. De acuerdo con la rutina ActualizarReloj (int, int, int) del programa
principal y de la rutina interfaz_driver del driver, indique cuál es el
mecanismo utilizado para pasar la información actualizada del reloj desde el
programa principal al driver y dónde es almacenada dicha información.
Ayúdese de la información de los puntos marcados como (P3). Justifique su
repuesta. (1 punto)
Como se ha visto en el ejercicio anterior, la rutina “ActualizarReloj” carga los
registros BX, CX y DX con los parámetros “hora”, “minutos” y “segundos”
respectivamente, que constituyen la información actualizada del reloj. Por tanto, la
rutina “interfaz_driver” recibe dicha información en esos tres registros
(mecanismo de paso de parámetros por registros) y la almacena en las
variables correspondientes del driver (ver índice P9).
P4. Complete las instrucciones marcadas con (P4). Ayúdese de los puntos
marcados con P3. Justifique su repuesta. (1 punto)
De acuerdo a lo indicado en los anteriores problemas P2 y P3, las instrucciones
marcadas con (P4) se completarían del siguiente modo:
mov hora, bx
mov minutos, cx
mov segundos, dx
P5. En las rutinas de servicio incluidas en el driver, ¿sería necesario enviar
el comando EOI a los PIC que corresponda en cada caso?. Justifique su
repuesta. (1 punto)
El driver incluye rutinas de servicio de las interrupciones 1Ch y 61h. Ambas
interrupciones son generadas desde software mediante la instrucción INT (la
primera es generada por la rutina de servicio del reloj del sistema y la segunda
por las rutinas de ensamblador indicadas en el ejercicio). Por tanto, al no ser
estas interrupciones generadas directamente por un dispositivo conectado a los
controladores de interrupción (PIC) 8259, no hay que enviar a los PIC ningún
comando de final de interrupción EOI.
P6. ¿Cuál es el mecanismo que utiliza el driver para indicar que está
residiendo en memoria cuando el programa principal lo comprueba?
Ayúdese del análisis de la zona de código alrededor de las líneas marcadas
con (P6). Justifique su repuesta. (1 punto)
El programa principal interroga al driver mediante una llamada a una función del
mismo (función 00h). Si el driver está instalado y operativo, devuelve en el
registro AX un valor característico 0F0F0h. El programa principal comprueba
después de la llamada a la función si el valor de AX es ése. Si no lo es, determina
que el driver no está instalado y operativo.
P7. ¿Qué mecanismo está utilizando el driver para calcular la hora en cada
momento, es decir, en base a qué se ha conseguido implementar un reloj en
tiempo real? Ayúdese del análisis de las líneas de código marcadas con (P7).
Justifique su repuesta. (1 punto)
El driver hace uso de las interrupciones periódicas del Timer del PC (PIT) que es
el encargado de mantener la hora y la fecha cuando el PC está funcionando. La
rutina asociada a las interrupciones del Timer (vector 08h) hace una llamada a
una interrupción software asociada al vector 1Ch cuya rutina de servicio no
hace nada por defecto. Dicha rutina de servicio del vector 1Ch, que se ejecuta
con cada interrupción del Timer, es sustituida por nuestra propia rutina de servicio,
que será la encargada de contar las interrupciones y de actualizar los contadores
asociados a la hora, minutos y segundos. No se usa el RTC para generar una
interrupción periódica que sea la base de tiempos del reloj en tiempo real que
necesitamos. Tenga en cuenta que nuestra rutina de servicio, asociada al vector
de interrupción 1Ch, es llamada mediante el mecanismo de interrupción software y
que, por tanto, no pasa por los PICs del PC como ocurre con las interrupciones
hardware externas.
P8. De acuerdo con el funcionamiento del código de la aplicación, tanto del
programa ejecutable (.EXE) como del driver (.COM), ¿funcionaría el reloj si
salimos del programa principal escrito en C? ¿Qué repercusiones tendría
salir del mismo?. Justifique su repuesta. (0.5 puntos)
Existen dos posibilidades, si salimos bien del programa principal, éste
desinstala el driver y por tanto, el reloj dejaría de funcionar. Si salimos mal, el
driver sigue instalado y por tanto, el reloj sigue funcionando. El problema es
que no podremos actualizar la hora ya que esto se hace desde el programa
principal.
P9. En el programa principal escrito en C y en el driver existen variables con
el mismo nombre. Ayúdese del análisis de las líneas de código marcadas
con (P9). De acuerdo con la implementación de la aplicación, razone las
siguientes preguntas:
P9.1 ¿Daría algún error la compilación del programa en C y el ensamblado
del driver debido a la utilización de variables con el mismo nombre?
Justifique su respuesta. (0.5 puntos)
No, son programas independientes en ficheros independientes. El programa en
C es compilado para generar su objeto, y lo mismo se hace con sus rutinas en
ensamblador, que serán ensambladas. Los objetos del programa principal en C y
de las rutinas en ensamblador serán montados para generar un ejecutable. El otro
programa, el driver, será ensamblado y montado como un programa
independiente, generando así otro ejecutable.
P9.2 ¿Podríamos utilizar el hecho de tener variables con el mismo nombre
para pasar la información de la hora, los minutos y los segundos desde el
programa principal al driver cada vez que queramos actualizar el reloj?
Justifique su respuesta. (0.5 puntos)
No, al ser programas independientes, es imposible conocer las direcciones
asignadas a las variables en un programa desde el otro y viceversa. Son variables
diferentes y no existe forma de conocer sus direcciones.
P9.3 Cuando ejecutamos el driver, ¿el reloj empezará a funcionar o
permanecerá parado mientras no ejecutemos el programa principal? ¿cuál
será la hora, los minutos y los segundos que mostrará el reloj en la pantalla
del PC si el formato es hh:mm:ss suponiendo que el reloj comience a
funcionar sin haber ejecutado el programa principal? Justifique su respuesta
en cada caso. (0.5 puntos)
Al ejecutar el driver y quedarse instalado, el reloj empieza a funcionar ya que el
código que lo implementa y las interrupciones que lo controlan dependen en
exclusiva del driver y no del programa principal. El problema es que las
variables asignadas a las horas, minutos y segundos están inicializadas a 0,
con lo que se mostraría una hora inicial 00:00:00. Tenga en cuenta que la
puesta en hora del reloj se realiza desde el programa principal en C.
Descargar