simplebooklet thumbnail

Estructura de Computadors I. Laboratori 1
Pr`actica 5
Objectius:
a) Programaci´o de subrutines.
b) Maneig de la pila.
c) Continuar amb l’escriptura de l’emulador de la m`aquina elemental.
Subrutines
En aquesta pr`actica comen¸careu a fer feina amb una estructura b`asica de la programaci´o en
assemblador: la subrutina. L’equivalent a les subrutines en els llenguatges d’alt nivell on els
procediments i les funcions. Una subrutina ´es un fragment de programa al qual es bota en ser
cridada, per`o de tal manera que en finalitzar la seva execuci´o es torna a la instrucci´o seg¨uent a
la que provoc`a el bot.
En el 68K la instrucci´o per cridar una subrutina ´es jsr (Jump to Subroutine) i la que
implementa el retorn de la subrutina ´es rts (Return from Subroutine). Dins una subrutina pot
haver-hi es d’un rts ja que pot acabar a diferents llocs depenent de les condicions.
La sintaxi completa de la instrucci´o de cridada ´es jsr label, on label ´es l’etiqueta del
comen¸cament de la subrutina. D’una altra banda, rts no fa servir cap argument.
La Pila del sistema
Una pila (en angl`es stack) ´es una forma d’organitzar dades prou important. En ella les
dades es posen una darrera l’altra a mode de cua, per`o amb la particularitat que aquesta cua
funciona com un caramull de plats: els elements es lleven en l’ordre invers a com han arribat, el
darrer que s’ha introdu¨ıt ´es el primer que es lleva. Aquest darrer element s’anomena cap de la
pila. Tots els processadors moderns gestionen una pila en mem`oria, on poden guardar diferents
tipus d’informaci´o.
En el cas del 68K, la pila creix des del final de la mem`oria $00FF FFFF cap a la posici´o 0.
Quan es crida una subrutina, el processador fa cr´eixer la pila per poder guardar una adre¸ca
de mem`oria (4 bytes), guarda l’adre¸ca de tornada a l’espai reservat (´es a dir, l’adre¸ca de la
instrucci´o que s’ha d’executar quan acabi la subrutina), i despr´es bota a la subrutina
1
. Quan
es retorna d’una subrutina, el processador treu l’adre¸ca de retorn del cap de la pila i allibera
l’espai corresponent.
El registre A7 del 68K ´es el punter de pila (stack pointer); tame vos podeu referir a aquest
registre com SP dins de l’emulador. El seu contingut ´es, sempre, l’adre¸ca del cap de la pila;
quan la pila est`a buida pren el valor $0100 0000.
1
Com veurem es endavant, la pila tame se pot fer servir pel pas de par`ametres i resultats.
Estructura de Computadors I. Laboratori 2
L’usuari pot introduir i treure dades de la pila (per seguretat useu sempre words o long words
i mai bytes). El 68K no t´e instruccions PUSH i POP, sino que fa servir instruccions MOVE amb
adre¸caments espec´ıfics:
PUSH x MOVE.S x, -(SP)
POP x MOVE.S (SP)+, x
Noteu que la definici´o de pila nom´es indica com es fiquen i treuen dades d’ella, per`o no com
s’hi ha d’accedir. No podeu introduir ni eliminar cap dada nova del mig de la pila, per`o podeu
llegir-les o modificar-ne qualsevol.
Subrutines de llibreria
A l’hora de dissenyar una subrutina els plantejaments possibles on dos: dissenyar la subru-
tina per ser emprada dins un programa en particular, fent ´us de dades del programa situades
dins registres o en posicions espec´ıfiques de mem`oria, ´es el que direm una subrutina d’usuari;
l’altra opci´o dissenya la subrutina per ser utilitzada amb qualsevol programa, l’anomenarem
subrutina de llibreria.
D’una subrutina de llibreria l’usuari sols necessita saber que fa, i no com ho fa. Evident-
ment, tame cal con`eixer com passar-hi els par`ametres necessaris i com extreure’n els resultats
(l’interf´ıcie de la subrutina). Per exemple, si es disposa d’una subrutina que calcula el producte
escalar de dos vectors, cal saber com indicar quins on els vectors a utilitzar i on apareixer`a el
resultat, mentres que el procediment usat per calcular el producte escalar ´es totalment irrelle-
vant.
Si la subrutina ha de poder-se usar dins qualsevol programa, s’ha d’implementar de manera
que el seu funcionament no es vegi afectat per la situaci´o de l’entorn en el moment de l’execuci´o,
o que al manco les restriccions que imposi siguin m´ınimes.
´
Es a dir que una subrutina de llibreria
no pot programar-se suposant que, per exemple, el registre D3 o la posici´o de mem`oria $100A
estan buits. Aix`o no significa que no pugui usar-se qualsevol dels registres o determinades
posicions de mem`oria, per`o com que s’ha de conservar el seu valor en finalitzar la subrutina,
abans d’utilitzar-los s’haur`a de salvar el seu contingut, de manera que es puguin recuperar
abans de retornar al programa principal. Per aconseguir aquesta independ`encia, les subrutines
de llibreria, normalment, utilitzen la pila del sistema.
Per exemple, si durant l’execuci´o d’una subrutina de llibreria es volen utilitzar els registres
D0, D2 i D3, i la subrutina necessita 4 words de mem`oria per guardar variables internes, el
principi i final de la subrutina seran:
Estructura de Computadors I. Laboratori 3
SUBR: MOVE.L D0,-(SP)
MOVE.L D2,-(SP)
MOVE.L D3,-(SP) ; salva el contingut dels registres
SUB.L #8,SP ; reserva 4 words
.
.
.
ADD.L #8,SP ; allibera l’espai per variables internes
MOVE.L (SP)+,D3
MOVE.L (SP)+,D2
MOVE.L (SP)+,D0 ; recupera el valor del registres
RTS
En aquesta assignatura, les subrutines de llibreria tamb´e faran servir la pila per fer el pas de
par`ametres, ´es a dir que el programa principal ficar`a a la pila els par`ametres per a la subrutina
i aquesta hi dipositar`a posteriorment els resultats. Suposem que, continuant amb l’exemple del
producte escalar, les especificacions indiquen que els par`ametres necessaris, que es passen a
traes de la pila, on per aquest ordre, les dues adreces d’inici dels dos vectors a multiplicar i la
longitud del vector. Despr´es de l’execuci´o, i tame segons les especificacions, en el cap de la pila
s’hi haur`a guardat el valor del producte escalar; aleshores, la part de programa corresponent a
la cridada de la subrutina i obtenci´o de resultats podria ser:
LEA A,A0
MOVE.L A0,-(SP) ; introdueix inici del primer vector.
LEA B,A0
MOVE.L A0,-(SP) ; introdueix inici del segon vector.
MOVE.W #N,-(SP) ; introdueix la longitud dels vectors.
JSR PRODESC ; crida la subrutina.
MOVE.W (SP)+,RESULT ; recupera el resultat.
ADD.L #8,SP ; ajusta valor del punter de pila.
Fixau-vos en aquest exemple que, just en acabar la subrutina, el resultat ocupa la posi-
ci´o que abans ocupava N, i que les adreces d’A i B encara es mantenen dins la pila. Despr´es
d’extreure el resultat l’stack pointer apunta a la posici´o ocupada per l’adre¸ca de B. La darrera
instrucci´o serveix per deixar el punter de pila apuntant al valor que tenia abans de la primera
instrucci´o de l’exemple. Si no es controla, per part del programa principal, aquest desajust entre
l’espai ocupat pels par`ametres d’entrada i resultats, la pila es va omplint d’informaci´o in´util i
es desbalancetja.
Com es pot observar en els exemples anteriors, el mode d’adre¸cament indexat, presentat
a la pr`actica 4, ´es especialment ´util pel maneig de la pila. Quan s’escriu una subrutina de
llibreria no es coneix l’estat inicial de la pila, per`o els par`ametres sempre ocuparan la mateixa
posici´o relativa respecte el cap de la pila. Aix´ı, i usant el mode indexat, 0(SP) sempre correspon
al cap de la pila, 2(SP) ´es la segona paraula de la pila, 4(SP) la tercera i aix´ı successivament.
Aix´ı ser`a aquest el tipus d’adre¸cament que far`a servir la subrutina per llegir els par`ametres de
la pila i per escriure-hi el resultat.
Estructura de Computadors I. Laboratori 4
El seg¨uent programa es correspondria amb l’exemple del c`alcul del producte escalar:
ORG $1000
N EQU 3
A: DC.W 4, 3, 1
B: DC.W 3, -2, 4
RESULT: DS.W 1
START:
LEA A,A0
MOVE.L A0,-(SP)
LEA B,A0
MOVE.L A0,-(SP)
MOVE.W #N,-(SP)
JSR PRODESC
MOVE.W (SP)+,RESULT
ADD.L #8,SP
MOVE.B #9,D0
TRAP #15
PRODESC:
MOVE.L D0,-(SP)
MOVE.L A0,-(SP)
MOVE.L A1,-(SP)
SUB.L #8,SP
MOVE.W 24(SP),D0
MOVEA.L 26(SP),A0
MOVEA.L 30(SP),A1
; calcul del producte escalar
ADD.L #8,SP
MOVE.L (SP)+,A1
MOVE.L (SP)+,A0
MOVE.L (SP)+,D0
RTS
END START
Estructura de Computadors I. Laboratori 5
Especificaci´o del programa que s’ha d’escriure durant aquesta sessi´o
Durant aquesta sessi´o continuarem amb la escriptura del programa emulador de la m`aquina
elemental que es va comen¸car a la pr`actica anterior. Concretament:
1. Heu de completar la implementaci´o de la fase de fetch. El fetch de l’einstrucci´o hauria de
consistir en tres subpasses:
a) Fer servir el valor contingut a EPC per accedir a la seg¨uent einstrucci´o.
b) Emmagatzemar l’einstrucci´o a l’eregistre EIR.
c) Incrementar l’eregistre EPC.
Cal notar que l’eregistre EPC s’ha d’incrementar d’un en un, tot i que esteim fent servir
un vector de words del 68K per introduir el nostre eprograma a l’emulador. El programa
aturar`a la seva execuci´o quan trobi l’einstrucci´o HALT.
2. Heu de convertir la part del programa que fa la descodificaci´o d’una einstrucci´o en una
subrutina de llibreria que tindr`a per a la seva primera instrucci´o l’etiqueta DESCO. El
programa principal, despr´es de fer el fetch de la seg¨uent einstrucci´o, invocar`a a la subrutina
amb el contingut de l’eregistre EIR. La subrutina tornar`a el codi num`eric entre 0 i 10 que
es va indicar a la pr`actica anterior i el programa principal l’escriur`a a la component del
vector CODE que correspongui.
El pas de par`ametres concret s’ha de fer de la seg¨uent manera. En primer lloc, el pro-
grama principal reservar`a un word a la pila perqu`e la subrutina pugui escriure el seu
resultat posteriorment. A continuaci´o el programa principal escriur`a a la pila el codi de
l’einstrucci´o contingut a EIR i invocar`a la subrutina.
La subrutina no haur`a de fer servir cap altra informaci´o externa que el par`ametre que
se li passa. En cas de necessitar variables per fer c`alculs (si no basten els registres) la
pr`opia subrutina haur`a de reservar les posicions necess`aries a la pila. No ha d’accedir a la
mem`oria, nom´es a la pila.
Recordeu que, pel fet de ser de llibreria, la subrutina salvar`a a la pila els registres que hagi
de fer servir. Despr´es d’escriure el resultat a la posici´o reservada a la pila, la subrutina
recuperar`a el valor dels registres salvats a la pila i retornar`a al programa principal. All`a
s’eliminar`a de la pila el par`ametre passat a la subrutina (incrementant el valor de l’SP) i a
continuaci´o es recuperar`a de la pila el resultat retornat per la subrutina. Com podeu veure
´es el programa principal qui s’ha d’encarregar de deixar l’stack pointer amb el mateix valor
que abans de botar a la subrutina.
No oblideu tornar a comprovar que totes les einstruccions es descodifiquen correctament.