72
ESTRUCTURA DE COMPUTADORS I (EC-1) Enginyeria Informàtica Quadern de Laboratori Carlos Álvarez Cristina Barrado Luis M. Díaz de Cerio Montse Fernández David López Àngel Olivé Joan Manel Parcerisa Jordi Tubella Miguel Valero Dept. d’Arquitectura de Computadors

Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

ESTRUCTURA DE COMPUTADORS I(EC-1)

Enginyeria Informàtica

Quadern de Laboratori

Carlos ÁlvarezCristina Barrado

Luis M. Díaz de CerioMontse Fernández

David LópezÀngel Olivé

Joan Manel ParcerisaJordi Tubella

Miguel Valero

Dept. d’Arquitectura de Computadors

Page 2: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

ments

s bases

guatges,

s poden

a feta

es al

lloc a

haver

des a

n molt

una

rendreu

ern. A

nceptes

s de 20

que

ran de

estan

sor que

Els laboratoris de EC-1

L’assignatura d’estructura de computadors 1 (EC-1) és una assignatura de coneixe

bàsics pel que respecta al funcionament de l’ordinador. En aquesta assignatura trobareu le

sobre les que creixen alguns dels conceptes de sistemes operatius, xarxes, compilació, llen

etc. També és una assignatura eminentment pràctica, on els coneixements teòrics adquirit

ser fixats i ampliats al laboratori. És per això que les pràctiques són molt orientades a la fein

a classe.

Obligatorietat de les pràctiques

Les pràctiques de l’assignatura no són obligatòries. Això vol dir que no heu de lliurar r

professor al final de cada sessió. La nota de laboratori s’obté per mitjà d’un examen que té

l’última sessió. El pes d’aquesta nota i la manera de calcular la nota final ja us la deuen

explicat a classe (o bé la podeu trobar a la guia docent).

Que no siguin obligatòries no vol dir que no cal fer-les. Les pràctiques estan orienta

fixar els coneixements adquirits a classe, per tant serveixen per entendre l’assignatura i só

útils per aprovar. Hem eliminat la obligatorietat per eliminar l’estrès que produeix lliurar

pràctica cada quinze dies, però recomanem que les feu: no us portarà massa temps i n’ap

molt.

I jo, que haig de fer al laboratori?

Hi ha cinc sessions de laboratori. A cada sessió li correspon un capítol d’aquest quad

cada capítol hi ha una secció anomenada “lectura prèvia” on es repassen breument els co

relacionats amb el contingut de la sessió corresponent. Aquesta lectura no us portarà mé

minuts i aprofitareu millor les hores de laboratori.

A l’apartat anomenat “Enunciats de la pràctica” trobareu la descripció de les activitats

s’han d’anar desenvolupant durant la sessió. De tant en tant trobareu exercicis que s’hau

contestar sobre el mateix enunciat. Identificareu fàcilment aquest exercicis perquè

emmarcats en quadres de color gris. Quan trobeu un exercici que no us surt, crideu al profes

us ajudarà a trobar la solució.

1

Page 3: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

quina

sala on

r

Per

usuari

na de

unciats

uesta

eu-vos

proper

i que,

t a les

com

I com es comença?

Les pràctiques són a les sales D6-003 i D6-003bis (el vostre professor us indicarà a

aula us toca). Per entrar als comptes de l’assignatura s’han de fer coses diferents segons la

sigueu. Un cop hagueu encès la màquina i aquesta hagi fet elboot, els de l’aula D6-003 heu d’entra

amb identificadorECIXX on XX és el número de PC al que esteu treballant (està indicat).

exemple, si esteu al PC número 6, el vostre nom d’usuari ésECI6, si és el número 13, doncs

ECI13. Els que estigueu a la sala D6-003bis (la més propera a l’entrada) teniu com a nom d’

ECI1XX . Per exemple, si esteu al PC número 6 teniu com a nom d’usuariECI106, mentre que si

esteu al 13, el vostre identificador ésECI113.

Un cop esteu al vostre compte, podeu accedir a 3 discos virtuals (a part del discA: ).

Al disc W: trobareu l’enunciat de les pràctiques als subdirectoris indicats. Aquesta zo

disc és comú per a tothom, i no hi podeu escriure. Per tant per treballar heu de copiar els en

a la vostra zona de treball.

El discU: es la vostra zona de treball. Hi ha una zona de treball per cada PC i en aq

podeu escriure, esborrar etc... El primer que heu de fer és copiar els enunciats al disc U:. Fix

que d’aquestes zones n’hi ha una per PC, però no per grup de pràctiques. Això vol dir que el

grup d’EC1 que treballi amb el mateix PC on esteu, farà servir la mateixa zona de treball (

per tant, esborrarà tot el que trobi). És molt important que, si voleu guardar-vos el que heu fe

pràctiques us feu una còpia en disquets.

El disc T: és per lliurar l’examen (el dia de l’examen, òbviament). Ja us explicarem

funciona al propi enunciat de l’examen.

2

Page 4: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

a en

eureu la

ssaran

Sessió 1: Introducció

Objectiu: En aquesta sessió aprendreu l’entorn de treball. Veureu quina pinta fa un program

assemblador, veureu com funcionen el traductor, ellinker i el debugger(tot i que deldebugger

només veurem unes poques comandes, que ampliarem a les properes sessions). També v

representació dels naturals i dels enters, i el funcionament d’una sèrie d’instruccions. Es repa

també els conceptes de registres,flags i instruccions per a la manipulació de bits.

Lectura prèvia:

L’entorn

Els passos habituals per fer un programa (en qualsevol llenguatge) són els següents: primer

es crea el programa escrivint-lo en el llenguatge font per mitjà d’un editor de programes. El resultat

és un fitxer en un llenguatge que pot entendre l’usuari, però no la màquina. Per traduïr-lo a

llenguatge màquina es fa servir un programa traductor. Aquest genera un fitxer amb la traducció del

vostre programa, però encara no és un fitxer executable. Un fitxer executable conté el programa

traduit més una sèrie de codi que ha de tenir tot programa que es vulgui córrer a una màquina

determinada. Aquest codi comú es troba a les anomenades biblioteques del llenguatge (language

libraries). L’encarregat d’ajuntar el vostre codi amb el codi d’aquestes biblioteques és un programa

anomenat muntador (linker). Així doncs, el següent pas és invocar el muntador, que generarà el

programa executable (veure la figura 1.1).

Editor

Traductorbiblioteca

del llenguatge

Muntador

PROG.ASM

PROG.OBJ

PROG.EXE

figura 1.1: Entorn típic de programació

3

Page 5: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

Durant el procés de creació d’un programa se solen produir errors. Hi ha dos tipus d’errors:

els sintàctics o detectables en temps de traducció, i els semàntics o detectables en temps

d’execució. Els errors sintàctics són, per exemple, escriure malament una instrucció o fer una

operació entre dos tipus de dades incompatibles. Aquests errors són detectats pel traductor i els

hem de solucionar abans de poder generar un executable.

Un cop tenim un programa sintàcticament correcte el podem executar, però això no implica

que el programa sigui correcte. Totes les instruccions poden ser correctes, però ens podem haver

oblidat de posar la condició de final d’un bucle (i que aquest no acabi mai) o que, senzillament, el

programa no faci el que nosaltres volem. Aquests errors només es poden detectar en temps

d’execució, i per tal d’eliminar-los fem servir un depurador de programes (debugger). Els

depuradors ens permeten executar el programa instrucció a instrucció i veure tots els valors que es

van calculant, de manera que podem trobar els errors.

En el laboratori farem servir l’editor edit de DOS. El traductor (que en el cas de traduir d’un

llenguatge assemblador a llenguatge màquina rep el nom d’assemblador), el linker i el debugger

seran els de Borland (TASM, TLINK y TD )

Quina pinta fa un programa en assemblador?

A la figura 1.2 teniu el codi de la primera pràctica que provarem.

.model large

.386

N EQU -3

.stack 100h

.dataA1 dd 1A2 dd -1A3 dd 77777777h.code.startupETIQ1: MOV EAX, A1 MOV EBX, A2 ADD EAX, EBX ADD EAX, N MOV A3, EAX.exitEND

Definició del model

Començamen del segment de dades

Començament del seg. de codi

Començament delprograma principal.

Final del prog. pral.Final del fitxer

Definició del segment de pila

Definició de constants

figura 1.2: Codi del programa INTRO1.ASM

4

Page 6: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

El codi que està ressaltatha d’aparèixer en qualsevol programa. Les comandes .model large

i .386 indiquen l’entorn en que ens mourem (model de treball i tipus d’instruccions). Després de la

definició del model, podem posar les constants que ens interessi. Les constants es defineixen com

a nomEQU valor. A partir d’aquest punt totes les aparicions d’una constant són substituïdes pel seu

valor (compte: NO és una variable, NO es troba a memòria).

A continuació es defineix el segment de pila per mitjà de la directiva .stack i el número de

bytes que volem dedicar a la pila (en aquest cas 100h bytes).

La directiva .data indica el començament del segment de dades. A partir d’aquest punt

declararem totes les variables globals que faci servir el nostre programa.

La directiva .code indica el començament del segment de codi. Al segment de codi estaran

els procediments i funcions del programa (com veurem en properes pràctiques) i el programa

principal. El programa principal és el codi comprés entre les directives .startup i .exit. El vostre

fitxer ha d’acabar necessàriament amb la directiva END.

Al començament i final del programa principal han d’anar una sèrie d’instruccions

obligatòriament, i que sempre són les mateixes. Aquestes instruccions NO les heu de posar

vosaltres, sinó que les afegeix el traductor substituïnt el .startup i el .exit per les instruccions

pertinents.

Com es compila i es linka un programa?

La traducció es fa amb el programa Turbo Assembler, amb la següent comanda:

tasm /zi nomprograma

NOTA: tant la comanda tasm com el vostre nom de programa (no fa falta extensió, només el

nom) pot estar en majúscules o minúscules. La opció de compilació /zi ha d’estar

OBLIGATÒRIAMENT en minúscules (si no, la ignora). Aquesta opció de compilació genera

informació que serà utilitzada després a l’hora de depurar el programa. El tasm genera un fitxer

nomprograma.obj.

Per muntar s’ha de fer:

tlink /v /3 nomprograma

NOTA: Novament, tant tlink com el nom del programa (sense extensió) pot estar en

majúscules o minúscules, mentre que les opcions /3 (que linka amb la biblioteca d’instruccions del

386) com /v (que fa que es deixi informació pel debugger) han d’estar en minúscules.

Un cop fet això ja tenim un executable nomprograma.exe que podem executar o depurar.

A partir d’aquest punt, ja treballarem amb l’ordinador en marxa.

5

Page 7: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

fitxer

ostre

rror de

alitzat

ostra

es i de

PU

b

feu un

ent de

a l’altre

eu de

e pila

ramat

zen tot

ostre

cutar-les

Enunciats de la sessió.

Activitat 1.A: Com començar.

Començarem amb el programa que heu vist a la figura 1.2, i que es troba al

INTRO1.ASM. Primer de tot, editeu-lo amb l’edit per veure’l (i practicar una mica):

edit intro1.asm

Un cop estigueu familiaritzats amb l’edit ja podeu fer servir el traductor:

tasm /zi intro1

Fixeu-vos que quan traduïu, sortiran una llista d’errors o bé una indicació de que el v

programa ha estat traduït correctament. No passeu al muntatge fins que no tingueu cap e

traducció (en aquest cas no n’haurien de sortir d’errors).

tlink /v /3 intro1

Igualment, el muntador us informarà de si tot el procés ha estat correcte. Un cop heu fin

amb èxit aquest procés, ja podeu entrar al Turbo Debugger:

td intro1

El td ofereix moltes possibilitats. Només explicarem les que ens interessen a la n

assignatura. Primer de tot, ens interessa veure la informació a nivell de contingut de registr

memòria. Per fer això anirem al menú principal (F10) escollirem la opció View (V) i la subopció C

(C). És a dir, premeu consecutivament les teclesF10-V-C. Ara podeu veure una nova pantalla am

informació per la depuració. El millor és veure aquesta pantalla el més gran possible, per tant

Zoom (premeu la teclaF5).

La pantalla que veureu està dividida en 5 zones, que contenen informació sobre el segm

codi, els registres, els flags, la pila i el segment de dades. Podeu passar de una subpantalla

prement la teclaTAB (figura 1.3).

Al començament, la pantalla de codi mostra el programa que voleu depurar. Si canvi

pantalla (per mitjà deTAB ) anireu (en aquest ordre) a la pantalla de registres, a la de flags, a la d

i a la de dades, tornant després a la de codi (proveu de fer-ho).

A la pantalla de codi, us trobareu que les primeres instruccions no són les que heu prog

vosaltres. Són les instruccions introduïdes per la directiva.startup, i les podeu veure a la figura 1.4.

Aquestes instruccions són sempre les mateixes, independentment del programa, i inicialit

l’entorn de treball (fixeu-vos que inicialitzen els registres ds, ss i sp). La primera instrucció del v

programa està després d’aquestes 7 instruccions, per tant, el primer que hauríeu de fer és exe

6

Page 8: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

da per

ostra

ciats

estes

mateix

ança

antalla

l vostre

i posar-vos a sobre de la primera instrucció pròpia del vostre programa (que està indica

l’etiqueta ETIQ1 (podeu veure com la informació sobre etiquetes es manté: abans de la v

primera instrucció hi ha un indicador #intro1#etiq1 que marca el nom del fitxer i l’etiqueta asso

a la instrucció).

Per executar una instrucció anirem al menú principal (F10), opcióRun (R), subopcióTrace

intro (T). Això executa una (i només una) instrucció. Hi han accions que es fan força sovint; aqu

tenen el que s’anomena un curtcircuït al teclat: una tecla o una combinació de tecles que fan el

sense necessitat de passar pel menú cada vegada. Per exemple, al costat deTrace intro trobareu el

seu curtcircuït (F7). Això vol dir que és equivalent ferF10-R-T que ferF7.

Per treballar, us recomanem que feu sempre el següent: primer executeu ambF7 les 7

instruccions del.startup (observeu com, conforme les executeu, a la pantalla de codi el cursor av

i com els registres i els flags que es modifiquen durant l’execució es veuen ressaltats a la p

respectiva). Un cop heu executat aquestes instruccions, esteu a la primera instrucció pròpia de

programa (identificada per #intro1#etiq1).

Pantalla de codi

Pan

talla

de

regi

stre

s

Pan

talla

de

flags

Pantalla depila

Pantalla de dades

TAB TAB

TAB

TAB

TAB

figura 1.3: Divisió de la pantalla altd

figura 1.4: Instruccions introduïdes per la directiva.startup

mov dx, “segm” ; segm pot canviar d’un PC a un altremov ds, dxmov bx, sssub bx, dxshl bx, 04mov ss, dxadd sp, bx

7

Page 9: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

a dada

(des de

A3, us

ent), la

stra,

es (per

e.

a

. El

ariables

ateixa

veu

cia

Tot i que per defecte els registres surten amb 16 bits, hauríeu de fer servir eltd amb els registres

de 32 bits. Per fer això, aneu a la pantalla de registres (amb elTAB ) i feu ALT-F10 (les dues tecles

simultàniament) i al submenú que surt escolliu la opció de registres amb 32 bits (R).

Per veure les dades del vostres programa teniu dues possibilitats: inspeccionar una únic

o controlar el segment de dades. Per a inspeccionar una dada podeu anar al menú principal

qualsevol subpantalla) per mitjà de la teclaF10, escollir la opcióData (D), subopcióInspect (I ). Una

finestra us preguntarà quina variable voleu veure. Per exemple, pregunteu per la variable

sortirà una finestra com la de la figura 1.5, que us indicarà la seva adreça (segment:desplaçam

longitud (byte, word, dword) i el seu valor decimal i hexadecimal (per sortir d’aquesta fine

premeuESC)

L’altre possibilitat és controlar el segment de dades. Si us aneu a la subpantalla de dad

mitjà deTAB ) podeu ferALT-F10 , subopcióGoto (G) i us preguntarà quina variable voleu veur

Si poseu A1 veureu com la pantalla de dades es situa a l’adreçaDS:0000 (que és on comença la dad

A1). Amb la opció d’inspecció descrita al paràgraf anterior podeu observar com A1 és aDS:0000 ,

A2 aDS:0004 i A3 a DS:0008 , per tant podeu controlar totes les variables a la mateixa finestra

problema és que la finestra de dades us mostra la pantalla byte a byte i, en aquest cas, les v

són de mida dword. Si voleu veure les dades del DS amb una mida diferent de byte, feu a la m

pantalla de dadesALT-F10 Display as (D) i escolliu mida entreByte,Word oLong (Nota: en aquest

punt, pel TD undouble word és unlong word); per tant en aquest cas s’ha d’escollir la opcióL .

Torneu a la pantalla de programa (TAB ) i anem a executar el programa pas a pas. Obser

que la primera instrucció mou aEAXla variable A1. Cada cop que hi ha una instrucció que referèn

Inspecting A3

@XXXX:0008

dword 2004318071 (77777777h)

adreça inicial desegment de dades(coincideix ambel registre DS)

desplaçamentde la dadarespecte DS

longitut de la dada

valor (decimal)de la dada

valor (hexadecimal)de la dada

figura 1.5: Finestra de inspecció d’una dada

8

Page 10: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

(veure

1

Si ara

a dir,

a memòria, a dalt de la pantalla surt la adreça implicada i el valor abans d’executar la instrucció

figura 1.6).

Si executeu les dues primeres instruccions veureu comEAXi EBXes carregen amb els valors

(00000001h) i -1 (FFFFFFFFh) respectivament. El resultat de sumarEAXi EBXes mostra a la figura

1.7.

Podeu comprovar que tant el registre com els flags que es modifiquen canvien de color.

executeu la segona suma (sumaEAX amb la constant N, que valia -3) sortirà el de la figura 1.8.

Abans d’executar la instruccióMOV A3, EAX observeu que:

a) A dalt de la pantalla us surt l’adreça i el valor de la posició de memòria implicada, és

A3 (ds:0008 77777777 ).

figura 1.6: Adreça i valor de la posició implicada en una

instrucció de memòria

ds:0000 00000001

ETIQ1: MOV EAX, A1

0000 0000 0000 0000 0000 0000 0000 0001 =EAX 1111 1111 1111 1111 1111 1111 1111 1111 =EBX

1 0000 0000 0000 0000 0000 0000 0000 0000

+

CF=1 SF=0

(el resultatés positiu)

OF=0(positiu mésnegatiu iguala positiu: nooverflow)

ZF=1

(el resultatés zero)

figura 1.7: Resultat de ADD EAX, EBX

9

Page 11: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

dreça i

iable

r,

jut

l que té

dada

plícit i

1 i A2

anc en

ue en

rt és al

b) A la pantalla del segment de dades podeu observar com, efectivament, aquesta és l’a

el valor implicats.

Si executeu la instrucció (F7) podeu veure com a la pantalla del segment de dades, la var

A3 ha canviat de valor.

Les dues últimes instruccions (mov ah, 4c i int 21) són afegides per la directiva.exit. Si les

executeu, el programa acaba. Llavors podeu sortir deltd (ALT-X ) o bé tornar a executar-lo (F7, us

dirà que el programa ha acabat, premeuRETURN, F7 i us preguntarà si voleu tornar-lo a carrega

premeuRETURN i ja torneu a estar al començament del programa).

Ara ja teniu una idea de les possibilitats deltd. Anem a repassar uns quants conceptes amb l’a

d’aquest programa.

Activitat 1.B: Enters i naturals.

Recordeu que quan es representa qualsevol dada a memòria, té un valor explícit (aquel

com a dada guardada en binari) i un valor implícit (aquell que té interpretada com un tipus de

determinat o com a instrucció). En aquest apartat volem que veieu la diferència entre valor ex

valor implícit interpretat com a natural o com a enter. Suposem dues variables de mida byte A

amb valors binaris 00110010b i 11000000b, respectivament. Completeu les caselles en bl

l’exercici 1.1.

Haureu observat que els valors són ben diferents segons la interpretació (valor implícit) q

feu. Calculeu ara la suma dels dos números i respongueu les preguntes de l’exercici 1.2.

Ara és el moment de comprovar si heu contestat correctament. L’enunciat d’aquesta pa

0000 0000 0000 0000 0000 0000 0000 0000 =EAX 1111 1111 1111 1111 1111 1111 1111 1101 =N

0 1111 1111 1111 1111 1111 1111 1111 1101

+

CF=0 SF=1

(el resultatés negatiu)

OF=0(positiu mésnegatiu iguala negatiu: nooverflow)

ZF=0

(el resultatno és zero)

figura 1.8: Resultat de ADD EAX, N

10

Page 12: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

a

per

Anem

b zeros

t

fitxer INTRO2.ASM (figura 1.9).

Assembleu-lo, munteu-lo i seguiu-lo amb eltd tal i com s’ha explicat a la primera part de l

pràctica. Executeu només les 3 primeres instruccions (fixeu-vos en l’ús dels registresAH i AL, que

formen part del mateix registre de 32 bits, l’EAX). Si la vostra resposta no era correcta analitzeu el

què.

El número resultant és de mida 1 byte. Si l’interpretem com a enter, és de signe negatiu.

ara a extendre aquest resultat de mida byte a mida double word. Aquesta extensió es pot fer am

(instruccióMOVZX) o fent una extensió de signe (instruccióMOVSX). Suposem que tenim el resulta

de la suma anterior als registresAL i BL. Ompliu les caselles en blanc de l’exercici 1.3.

Valor explícit(binari)Variable

A1

A2

00110010

11000000

Valor explícit(hexadecimal)

Valor implícit(com a natural

Valor implícit(com a enter

exercici 1.1

en decimal) en decimal)

Valor explícit(binari)

0 0 1 1 0 0 1 0

1 1 0 0 0 0 0 0Valor explícit(hexadecimal)

Valor implícit(com a natural

Valor implícit(com a enter

+

= = =

Quin és el valor final delflags? CF= OF= ZF= SF=

És el resultat final correcte interpretat com a natural?

És el resultat final correcte interpretat com a enter?

exercici 1.2

en decimal) en decimal)

11

Page 13: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

Comproveu executant el programa si ho heu fet correctament.

.model large

.386

.stack 100h

.dataA1 db 00110010bA2 db 11000000b.code.startupETIQ1: MOV AL, A1 MOV AH, A2 ADD AL, AH MOV BL, AL MOVZX EAX, AL MOVSX EBX, BL.exitEND

figura 1.9: Programa INTRO2.ASM

Contingut(binari)Registre

AL=BL

Contingut(hexadecimal)

S’executa la instruccióMOVZX EAX, AL

Contingut d’EAX?

binari hexa

S’executa la instruccióMOVSX EBX, BL

Contingut d’EBX?

binari hexa

exercici 1.3

Anota el valor d’AL i BL després d’executarMOV BL, AL

12

Page 14: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

010b.

Activitat 1.C: Instruccions lògiques

Suposem que tenim dues variables de mida byte A1 i A2 amb valors 11110000b i 10101

Calculeu el resultat de fer una operacióAND i una operacióOR entre les dues variables.

Per comprovar el resultat tenim el programa INTRO3.ASM

Executeu les 6 primeres instruccions (sense contar les del.startup) i comproveu les vostres

respostes.

Valor(binari)Variable

A1

A2

1 1 1 1 0 0 0 0

1 0 1 0 1 0 1 0

Valor(hexadecimal)

Valor(binari)

1 1 1 1 0 0 0 0

1 0 1 0 1 0 1 0

A1 AND A2

binari hexa

A1 OR A2

hexabinari

exercici 1.4

.model large

.386

.stack 100h

.dataA1 db 11110000bA2 db 10101010b.code.startupETIQ1: MOV AL, A1 MOV BL, A2 AND AL, BL MOV AH, A1 MOV BH, A2 OR AH, BH NOT AX MOV BX, 1000000000000000b BT BX, 15 BT BX, 14.exitEND

figura 1.10: Programa INTRO3.ASM

13

Page 15: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

és

pliu les

El resultat de la instruccióANDés aAL i el resultat de la instruccióORés aAH, quin serà el

resultat de fer unNOT AX?

Executeu amb eltd la instruccióNOT AX i comproveu la vostra resposta.

La instrucció Bit Test (BT) carrega alCF un bit del primer operand. El bit que es carrega

indicat pel segon operand (els bits es compten de dreta a esquerra i començant per 0). Om

caselles en blanc.

Un cop contestat, comproveu la vostra resposta amb ajut deltd.

AX

binari hexa

NOT AX

binari hexa

exercici 1.5

BX

binari hexa1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 0 0 0

BT BX, 15 CF ?

BT BX, 14 CF ?

exercici 1.6

14

Page 16: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

ió. Les

e un).

om a

ra,

Activitat 1.D: Rotacions i desplaçaments.

En aquest apartat veurem el funcionament de les instruccions de desplaçament i rotac

instruccions de desplaçament poden ser lògiques o aritmètiques.

Els desplaçaments lògics desplacen els bits del valor font introduïnt zeros (un o més d

L’últim bit que surt del valor font és emmagatzemant alflag CF (figura 1.11).

Els desplaçaments aritmètics fan el mateix, però mantenint el signe (figura 1.12).

Les instruccions de rotació també desplacen, però el bit que surt del valor serveix c

realimentació. Les instruccions deROLi RORfan que el bit desplaçat afora sigui el mateix que ent

a més de deixar una còpia alCF (figura 1.13).

SHR

0

CF

SHLCF

0

figura 1.11: Instruccions de SHIFT

SARCF

SAL (Fa el mateix que elSHL)CF

0

figura 1.12: Instruccions de SHIFT aritmètic

ROR CF

ROLCF

figura 1.13: Instruccions de rotació

15

Page 17: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

e

bans

Les instruccions de rotació amb carry (RCR, RCL) funcionen de manera similar, però el bit qu

entra és el que hi havia alCF i el que surt va a parar alCF (figura 1.14).

També hi ha instruccions per posar elCF a 1 (STC), a 0 (CLC) i invertir-lo (CMC).

Per provar aquestes instruccions farem servir el programa INTRO4.ASM (figura 1.15). A

d’executar-lo feu l’exercici 1.7 i comproveu els resultats amb eltd.

RCR

CF

RCL

CF

figura 1.14: Rotacions amb carry

.model large

.386

.stack 100h

.dataA1 dd 80000000h.code.startupETIQ1: MOV EAX, A1 SHR EAX, 1 SHR EAX, 3 MOV EBX, A1 SAR EBX, 1 SAR EBX, 3 MOV ECX, A1 ROL ECX, 1 ROL ECX, 1 ROL ECX, 8 MOV EDX, A1 STC CLC RCL EDX, 1 RCL EDX, 1 RCL EDX, 1 STC RCL EDX, 1.exitEND

figura 1.15: Programa INTRO4.ASM

16

Page 18: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

gma

rands

ó a la

són

ts, 2 de

Activitat 1.E: Instruccions de multiplicació.

Les instruccions de multiplicació i divisió al processador intel 386 són el paradi

d’instruccions que admeten moltes possibilitats, tant a nivell de mida d’operands, número d’ope

i operands implícits. Primer farem una petita explicació del seu funcionament (més informaci

documentació “Manual del 386”).

La instruccióMULrealitza una multiplicació de naturals. Té un únic operand (els altres

implícits) i aquest operand pot ser de mida byte, word o double word (i pot estar a memòria o a un

registre). Recordeu que multiplicar dos números de 8 bits té com a resultat un número de 16 bi

A1 dd 80000000h

Instrucció EBX (binari) CF

MOV EBX, A1

SAR EBX, 1

SAR EBX, 3

Instrucció EAX (binari) CF

MOV EAX, A1

SHR EAX, 1

SHR EAX, 3

Instrucció ECX (binari) CF

MOV ECX, A1

ROL ECX, 1

ROL ECX, 1

ROL ECX, 8

Instrucció EDX (binari) CF

MOV EDX, A1

STC

CLC

RCL EDX, 1

RCL EDX, 1

RCL EDX, 1

STC

RCL EDX, 1

exercici 1.7

17

Page 19: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

s és que

e 32

l, E

uadres

heu

e

ARI

no. La

aquest

rvir les

, per

un

;

.

e,

16 bits donen un de 32, i dos de 32 en donen un de 64 bits.

Per tant podem realitzar una multiplicació amb operands de 8 bits fent

MUL op8

Quin és l’altre operand? On es deixa el resultat? La resposta a aquestes dues pregunte

tant l’altre operand font com l’operand destí són implícits (i són el registreAL i AX, respectivament).

Per tant, la operació que es fa és

AX = AL * op8

Pel que respecta a la multiplicació amb operands de 16 bits, l’operand implícit ésAX i els 32

bits de resultat s’emmagatzemen de la següent manera: els 16 bits alts es guarden alDXi els 16 baixos

al registreAX

Amb la mateixa filosofia, els 64 bits resultants de fer una multiplicació de dos elements d

bits es guarden al registresEDX (els 32 de més pes) i aEAX (els de menys pes).

Per il.lustrar aquest problema, anem a multiplicar 7 per 2. El resultat (14 decima

hexadecimal) ocupa menys d’un byte, per tant podem provar els 3 casos. Completeu els q

blancs de l’exercici 1.8 (i ratlleu la part dels registres que no es modifiquen).

A la figura 1.16 teniu el codi del fitxer INTRO5.ASM, que conté el codi per provar si el que

fet és correcte. Executeu només fins a l’etiquetaETIQb1 . Abans de llistar el codi, noteu un parell d

coses: al llarg del programa, els registres s’inicialitzen amb certs valors. Això NO ÉS NECES

fer-lo. En aquest programa està fet per que noteu quina part del registre es modifica i quina

segona cosa que heu de observar és que només s’han definit dues variables A1 i A2 per

problema, ambdues de mida double word. Per fer les operacions sobre byte i word es fan se

directives BYTE PTR i WORD PTR. Si no es fessin servir, el compilador es queixaria doncs

exemple, la instruccióMOV AL, A1intentaria moure una variable definida com de 32 bits (A1) a

registres de 8 bits (AL).

La instruccióIMUL fa una multiplicaciótenint en compte el signe. Pot tenir 1, 2 o 3 operands

en el cas de tenir un operand, funciona exactament igual que laMUL(però tenint en compte el signe)

Per il.lustrar les diferències entreMULi IMUL multiplicarem dos enters codificats en 1 byt

MUL op16

32 bits

DX AX

16 bits 16 bits

= AX * op16

MUL op32

64 bits

EDX EAX

32 bits 32 bits

= EAX * op32

18

Page 20: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

em els

blanc de

rand

xò vol

bits alts

amb valors 0A6h (-90 considerat com a enter, 166 considerat com a natural) i 04h. Si consider

números com a enters o com a naturals, els resultats seran diferents. Ompliu les caselles en

l’exercici 1.9.

Executeu el programa amb eltd fins la etiquetaETIQb2 i comproveu el resultat.

La instruccióIMUL pot tenir també 2 i 3 operands. En el cas de tenir-ne dos, el primer ope

fa de font i destí, i no està limitat a ser AX (pot ser qualsevol registre). Per exemple

IMUL BX, CX fa BX = BX * CX

Noteu que el resultat podria ocupar fins a 32 bits, però es guarda en un registre de 16. Ai

dir que només es guardaran els 16 bits baixos del resultat, i si el resultat és més gran, els 16

AL= 07h BL=02hMUL BL

EAX?

AH AL

AX

DH DL

DX

EDX?

AX= 0007h BX=0002hMUL BX

EAX?

AH AL

AX

DH DL

DX

EDX?

EAX= 00000007h EBX=00000002hMUL EBX

EAX?

AH AL

AX

DH DL

DX

EDX?

exercici 1.8

AL= 0A6h BL=04hMUL BL

AX?

AL= 0A6h BL=04hIMUL BL

AX?

Valor decimal com a natural? Valor decimal com a enter?

exercici 1.9

19

Page 21: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

.model large

.386

.stack 100h

.dataA1 dd 00000007hA2 dd 00000002hB1 db 0A6hB2 db 04hB3 dw 0FFA6hC1 dw 0301hC2 dw 0003hC3 dd 00000301hC4 dd 00000003h.code.startupETIQa1: MOV EAX, -1 MOV EDX, -1 MOV AL, BYTE PTR A1 MUL BYTE PTR A2ETIQa2: MOV EAX, -1 MOV EDX, -1 MOV AX, WORD PTR A1 MUL WORD PTR A2ETIQa3: MOV EAX, -1 MOV EDX, -1 MOV EAX, A1 MUL A2ETIQb1: MOV AL, B1 MUL B2 MOV EBX, EAX MOV EAX, 0 MOV AL, B1 IMUL B2ETIQb2: MOV CX, B3 IMUL CX, 04hETIQb3: IMUL BX, B3, 04hETIQc1: MOV EAX, -1 MOV EDX, -1 MOV AX, C1 CWD DIV C2ETIQc2: MOV EAX, -1 MOV EDX, -1 MOV EAX, C3 CDQ IDIV C4.exitEND

figura 1.16: Programa INTRO5.ASM

20

Page 22: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

perand

ria o un

tí ha

l’altre

teix

doble

r la

te (una

bits

es perden. El mateix passa amb multiplicacions amb operands de 32 bits. A més, el primer o

ha de ser per força un registre, mentre el segon pot ser un registre, una adreça de memò

immediat.

En el cas de l’IMUL amb 3 operands, el primer és el destí i els altres dos els fonts. El des

de ser per força un registre, el primer font pot ser un registre o una posició de memòria, mentre

font només pot ser un immediat. Per exemple:

IMUL BX, B3, 04h BX = B3 * 4

Comproveu el funcionament d’aquestes instruccions executant amb eltd fins a l’etiqueta

ETIQc1.

Activitat 1.F: Instruccions de divisió.

Les instruccionsDIV i IDIV realitzen una divisió (de naturals o enters) i segueixen el ma

patró:

DIV dada

IDIV dada

On dada és el divisor i pot ser de 8, 16 o 32 bits. En qualsevol cas, el dividend ocupa el

de bits que el divisor. La operació retorna la divisió entera i el residu.

Si l’operand és de 8 bits es fa

AL = AX div dada8 ; AH = AX mod dada8 .

Si l’operand és de 16 bits el dividend és de 32 bits, on el 16 alts són aDXi els 16 baixos són aAX:

AX = DX:AX div dada16; DX = DX:AX mod dada16

Si l’operand és de 32 bits, el dividend és de 64 i es guarda aEDX(els 32 alts) i aEAX(els 32

baixos):

EAX = EDX:EAX div dada32; EDX = EDX:EAX mod dada32

COMPTE: si el quocient ocupa més bits dels del registres destí (AL, AX, EAX) llavors es

produeix un errordivisió per zero). Ho notareu perquè el programa s’atura i treu un missatge pe

pantalla.

Per tal de poder fer aquestes operacions és necessari tenir el dividend en el format correc

part aEAXo AX i l’altre a EDXo DX). Existeixen dues instruccions per convertir enters de 16 a 32

en formatDX:AX i 32 a 64 en EDX:EAX .

21

Page 23: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

u els

no es

CWD (Convert Word to Double word) no té operadors (són implícits) i fa

DX:AX <- Extensió de signe del registreAX

CDQ (Convert Double word to Quad word) funciona de la mateixa manera:

EDX:EAX <- Extensió de signe del registreEAX

Per provar-lo executeu la última part del programa INTRO5.ASM, però abans conteste

espais en blanc de l’exercici 1.10 i de l’exercici 1.11 (ombrejar la part dels registres que

modifica).

C1=0301h C2=0003h

EAX?

AX

AH AL

EDX?

DX

DH DLInstrucció

MOV AX, C1

EAX?

AX

AH AL

EDX?

DX

DH DL

CWD

EAX?

AX

AH AL

EDX?

DX

DH DL

DIV C2

exercici 1.10

C3=00000301h C4=00000003h

EAX?

AX

AH AL

EDX?

DX

DH DLInstrucció

MOV EAX, C3

EAX?

AX

AH AL

EDX?

DX

DH DL

CDQ

EAX?

AX

AH AL

EDX?

DX

DH DL

IDIV C4

exercici 1.11

22

Page 24: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

nt

mputa-

ències

Sessió 2: Tipus de dades i modes d’adreçame

Objectiu: En aquesta sessió repassarem la representació de la informació a la memòria del co

dor: veurem la definició i ús de punters, vectors i matrius. També veurem com programar sent

complexes comif-else i els buclesfor i while.

Lectura prèvia

Tipus de dades

Punters: un punter ocupa 32 bits i conté una adreça de memòria en format

segment:desplaçament, com es mostra a la figura 2.1.

Per inicialitzar aquest punter, es pot fer a la pròpia declaració del punter (figura 2.2a) o bé fer

el codi amb ajut de la instrucció LEA, que deixa al destí el desplaçament de la variable font (figura

2.2b).

@PX

4A

E300

12

figura 2.1: Exemple de punter

Suposem que ds=4AE3hi que tenim una

variable X a ds:0012

Una variable PX que fos un

valor 4AE3:0012

punter a X tindria el

X db ?PX dd X

a)

X db ?PX dd ?

...LEA AX, X ; carrega en AX el

;el desplaçament d’XMOV WORD PTR PX, AXMOV WORD PTR PX+2, DS; sabem que

;X és al segment de dades

b)

figura 2.2: Inicialització d’un punter a) a la pròpia declaració

i b) via codi.

23

Page 25: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

e

ent del

ent 1

t, l’accés

ix en

nt 4

questa

ments

emòria

a

oc

nts del

ytes

tenir

Vectors: tots els elements d’un vector s’emmagatzemen en un únic bloc de memòria a partir

d’una adreça determinada, els diferents elements s’emmagatzemen en posicions consecutives de

manera que l’element i està entre l’i-1 i l’i+1 (figura 2.3). Els vectors estan definits sempre a partir d

la posició 0. El propi índex indica quants elements ens hem de desplaçar des del començam

primer element (per accedir a l’element 0 hem de saltar-nos 0 elements, per accedir a l’elem

hem de saltar-nos 1 element, etc... en general, per accedir a l’element amb índexi ens hem de saltar

els i elements anteriors)

Si l’emmagatzematge és com el del llenguatge C (int v[N]; ), llavors a partir de l’adreça de

v ja es troben tots els elements (ocupant 4 bytes cada element, donat que són enters). Per tan

a l’elementv[i] és com segueix:

v[i] = M d[@v + i*4]

Si pel contrari estem parlant d’un vector tipus JAVA, llavors l’emmagatzematge es produe

dues parts de memòria: el punter a les dades i les dades en si. Si definim un vectorv com a int v[]

= new int[N]; la variablev apunta a una posició de memòria on hi ha un punter (ocupa

bytes) que, al seu temps, apunta a un únic bloc de memòria on hi ha la informació del vector. A

informació consta d’un enter (4 bytes sempre) en la primera posició, que indica el número d’ele

del vector, i a continuació tots els elements emmagatzemats en posicions consecutives de m

(figura 2.4). Si volem accedir av[ i ] (l’element del vector amb índexi), hem de fer dos accessos

memòria: el primer a la posicióv per tal de trobar el punter a la informació del vector. En el ll

apuntat per aquest punter, i amb desplaçament 0, trobaríem la longitud en nombre d’eleme

vector (v.length ). L’elementi està a l’adreça que indica el punter més 4 (per saltar-nos els 4 b

de la longitud) mési*B, essent B la grandària en bytes de cada element. En resum, per ob

...

v[0]

v[1]

v[2]

v[n-2]

v[n-1]

@v[0]

N elements (si cada element ocupa B bytes, N*B bytes)

figura 2.3: Representació d’un vector a memòria

24

Page 26: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

A no

siderar

ltre

v.length hem de fer:

v.length = Md[Mref[@v]]

Al seu temps, per obtenir l’element v[i] es fa fent:

@v[0] = Mref[@v] + 4

v[i] = M d[@v[0] + i*B]

o bé

v[i] = M d[Mref[@v] + 4 + i*B]

Matrius bidimensionals: una matriu bidimensional de NxM elements s’emmagatzema en

un únic bloc a memòria. Interpretem una matriu de NxM com una matriu de N files de M elements

cadascuna. Si cada element de la matriu ocupa B bytes, llavors la matriu ocupa un bloc de MxNxB

bytes (veure figura 2.5a).

Dins d’aquest bloc, els elements s’emmagatzemen per files, primer es guarden tots els

elements de la fila 0, després els de la fila 1, etc... Dins de cada fila, els elements estan ordenats

per columnes (figura 2.5b).

Per tant, per accedir a l’element mat[i][j] haurem de saltar i files completes (de M elements

de B bytes), i després j elements de B bytes (suposem una matriu d’enters, B=4 bytes). És a dir, la

fórmula per obtenir un element mat[i][j] serà:

mat[i][j] = M d[@mat + ((i*M)+j)*B]

El sistema anteriorment descrit serveix per a matrius tipus llenguatge C. El llenguatge JAV

admet matrius bidimensionals com a tals, però admet vectors de vectors, per tant podem con

una matriu deNxM elements com un vector deN elements on cadascun és, al seu temps, un a

...

length

v[0]

v[1]

v[n-2]

v[n-1]

@v

figura 2.4: Representació d’un vector JAVA a memòria

int v[] = new int[N];

v[]

TV: mida vectorN elements,cada element de B bytesTV: N*B bytes T

V+

4 by

tes

@v[0]

25

Page 27: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

M

N

fila i

columna j

int mat[N][M];

@mat

NxMelementsNxMxBbytes

figura 2.5: a) Format d’una matriu C de N files i M

columnes i b) organització per files

...

fila

0m

at[0

,*]

fila

1m

at[1

,*]

fila

N-1

mat

[N-1

,*]

mat[1,0]mat[1,1]

mat[1,M-1]

mat[1,2]

a)

b)

26

Page 28: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

ça de

vector deM elements (int mat2[][]= new int[N][M] , figura 2.6).

La manera d’obtenir un element mat2[i][j] és una mica més complexa:

@mat2[0] = Mref[@mat2] + 4

@mat2[i][0] = Mref[@mat2[0] + 4*i] + 4

mat2[i][j] = Md[@mat2[i][0] + 4*j]

És a dir, un primer accés per trobar la llista de punters a les files, un altre per trobar l’adre

la fila i, i un altre per trobar l’elementj , desplaçant-nos per la filai.

Modes d’adreçament

Els modes d’adreçament ens indiquen on són les dades implicades en una instrucció en

llenguatge màquina. Les dades poden ser a la pròpia instrucció (mode immediat), en un registre

...

N

mat2[0][]

@mat2

figura 2.6: Representació d’una matriu JAVA a memòria

int mat2[][] = new int[N][M];

mat2[]

mat2[1][]

mat2[N-2][]

mat2[N-1][]

...

M

mat2[0][0]

mat2[0][1]

mat2[0][M-2]

mat2[0][M-1]

...

M

mat2[1][0]

mat2[1][1]

mat2[1][M-2]

mat2[1][M-1]

etc

@mat2[0]

27

Page 29: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

(mode registre) o a la memòria, i en aquest cas el mode pot ser absolut, indexat, indirecte,

desplaçament o una combinació dels anteriors i, en general és de la forma:

RS:constant[RB+RI*E]

• RS o registre de segment: pot ser qualsevol registre de segment (cs, ss, ds, es, fs, gs). Això

força el segment on es buscarà la dada. La resta de l’expressió indica el desplaçament dintre del

segment. Si no es posa registre de segment es considera per defecte el de dades (ds), excepte

en el cas que un dels registres sigui l’EBP o l’ESP, en aquest cas es considera per defecte el de

pila (ss).

• constant: pot ser qualsevol valor constant (etiquetes, números, constants, operacions entre con-

stants etc..). Si s’inclou algun símbol referent a una variable, el TASM avaluarà l’expressió sub-

stituint aquest símbol pel seu desplaçament respecte al seu segment, i NO PEL SEU VALOR (ja

que el valor li és desconegut)

• RB o registre base: pot ser qualsevol registre de 32 bits

• RI o registre índex: pot ser qualsevol registre de 32 bits, tret de l’ESP

• E o factor d’escalat: ha de ser un valor 1, 2, 4 o 8.

Sentències estructurades

En aquest punt veurem les sentències que defineixen un bucle (for i while) i la sentència

condicional (if-else) i la seva traducció a assemblador.

Les estructures for i while es poden executar un mínim de 0 iteracions (si el valor inicial és

superior al final en el for, i si la primera vegada no es compleix la condició en el while). La traducció

de les sentències for i while es pot veure a la figura 2.7.

Pel que respecta a la sentència if-else, la seva traducció seria com la indicada a la figura 2.8.

En tots aquests exemples s’han suposat variables enteres de 32 bits. Si les dades són d’un

altre tipus o grandària (o bé la condició del si és diferent), llavors cal que les adapteu al problema

que esteu programant.

28

Page 30: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

int vi,vf;for (int i=vi; i<=vf; i++)

{cos del bucle}

i = vi;while (i<=vf)

{cos del buclei++;}

Suposem que el valor inicial és a lavariable vi i el valor final a lavariable vf . Farem servir el registreesi com a variable d’inducció i .VI dd 0VF dd 99

MOV ESI, VIbucle: CMP ESI, VF

JG fibucle;cos del bucleINC ESIJMP bucle

fibucle:

figura 2.7: Traducció de les estructuresfor i while

Suposem que els valors inicials d’ a ib són als registres eax i ebx

CMP EAX, EBXJNE sino; codi_llavorsJMP final

sino:; codi sino

final: ...

figura 2.8: Traducció d’una estructuraif-else

if (a==b){codi_llavors}

else{codi_sino}

29

Page 31: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

vector

ent la

mb

teu

poc

on

Enunciats de la sessió

Activitat 2.A: Vector de tipus C

En aquest primer apartat, estudiarem un bucle que fa la suma de tots els elements d’un

de tipus C. El vector es diu v_C, i té 8 elements de tipusshort (enter de 16 bits). L’algorisme que

realitza la suma dels elements el podeu trobar a la figura 2.9a.

Si analitzeu el codi en assemblador (figura 2.9b), veureu que es recorre tot el vector, f

suma sobre el registreax i omplint la variable suma amb el resultat al final del bucle.

El codi de la figura 2.9.b el teniu al fitxer TDMA1.ASM. Compileu i munteu el programa a

el tasm i el tlink . Ara anem a executar l’algorisme amb eltd. Per veure el funcionament, podem

executar un parell d’iteracions ambF7 i veure com els valors dels registres van variant. Si execu

un parell d’iteracions ambF7 veureu que el fet d’executar instrucció a instrucció de vegades és

útil. Per accelerar això podem fer servir els punts d’aturada obreakpoints.

Per instal-lar unbreakpointhem de fer servir el cursor per situar-nos a sobre de la instrucció

volem posar el punt d’aturada. Amb els cursors, situeu-vos a sobre de la instrucciójmp bucle1 i feu

F10, opcióBreakpoint, subopcióToggle (o utilitzeu el curtcircuïtF2). Veureu com la instrucció ha

short v_C[8];short suma;

suma=0;for (int i=0; i<8; i++)

{ suma += v_C[i];}

a)

.code

.startupmov esi, 0

mov ax, 0 mov ecx, 8bucle1: cmp esi, ecx je fi_bucle add ax, v_C[esi*2] inc esi jmp bucle1fi_bucle: mov suma,ax.exit

b)

figura 2.9: a) algorisme bàsic en alt nivell i b) la seva traducció a assemblador.

30

Page 32: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

b un

nt

odeu

u

21)

Si voleu

u

com

xer

ts

ix un

eu

quedat marcada. Es pot executar el programa amb unrun (F10, opció Run, subopcióRun o el

curtcircuït F9). En aquest cas, el programa s’executarà fins que trobi una instrucció am

breakpointo fins que el programa finalitzi. Si executeu ambF9, veureu que sempre us atureu al pu

on vàreu posar elbreakpointi que cada vegada heu executat una iteració completa. Amb això p

fer una execució completa. Tres comentaris respecte delsbreakpoints i l’opció run:

1) Per eliminar elsbreakpointsésF10opcióBreakpoint, subopcióDelete all, que elimina TOTS

els punts d’aturada. Si voleu eliminar només unbreakpoint, situeu-vos a sobre de la instrucció i fe

F10, opcióBreakpoint, subopcióToggle (o utilitzeu el curtcircuïtF2). Veureu com la instrucció deixa

d’estar marcada.

2) En qualsevol punt del programa podeu tornar a començar fentF10, opció Run, subopció

Program reset (curtcircuïtCtrl-F2 ).curtcircuït

3) Si feu unrun i arribeu al final de tot, penseu que quan s’executa l’última instrucció (INT

les dades que hi ha al segment de dades o als registres poden no ser les del vostre programa.

estar segurs, poseu unbreakpointa la instrucció MOV AH, 4Ch (la d’abans del INT 21) i comprove

llavors les vostres dades.

Podem comprovar el resultat seguint les sumes parcials al registreax o bé mirant el resultat

final a la variablesuma. Per mirar el resultat de la variable podem veure què hi ha a memòria asuma

(un cop executada la instrucció etiquetada com a fi_bucle, que mou el resultat asuma), anant a la

pantalla de memòria (per mitjà delTAB ) i mostrant el resultat (ALT-F10 G escrivintsuma). Per

veure-la en formatword (és unshortde Java), hem de ferALT-F10 D i escollirword (el resultat és

329 = 0x0149).

Una altra manera de veure-ho és fer una inspecció del valor d’aquesta variable (F10, opcióData,

subopcióInspect i poseusuma). Recordeu que aquesta finestra us mostra tant el valor decimal

l’hexadecimal (per tant 0x149, 329).

Ara anem a modificar una mica el programa. Copieu TDMA1.ASM en un altre fit

TDMA2.ASM (feucopy TDMA1.ASM TDMA2.ASM). Volem que faci la suma de tots els elemen

del vector v_C2, que ja està definit amb tots els elements de midashort (16 bits).

Feu l’exercici 2.1 i acabeu-lo abans de continuar llegint.

Si heu fet l’exercici 2.1 haureu comprovat que la suma dels valors d’aquest vector produe

overflowsobre unshort . Per tant hem de deixar el resultat de la suma sobre unint suma2 (32

bits).

Implementeu sobre el codi del fitxer TDMA2.ASM l’algorisme de la figura 2.10. Comprov

executant amb el td que el resultat de suma2 és el correcte (36000 = 0x00008CA0)

31

Page 33: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

exercici 2.1

Traduïu el número 36000 a binari:

Els elements del vector v_C2 són:

32000, 4333, 328, -123, 4, -555, 34, -21 suma= 36000

Interpreteu el resultat com a enter de 16 bits i traduïu-lo a decimal,

quant dóna?

es pot representar el número enter 36000 en 16 bits?

short v_C2[8];int suma2;

suma2=0;for (int i=0; i<8; i++)

{ suma2 += (int)v_C2[i];}

figura 2.10: Nou algorisme.

32

Page 34: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

suma

1.

saber

Activitat 2.B: Vectors de tipus Java

Copieu el fitxer TDMA1.ASM a TDMA3.ASM (copy TDMA1.ASM TDMA3.ASM). Si

l’editeu, veureu que també hi ha definit un vector en tipus Java (v_JAVA), de tipusshort i de 8

elements, que coincideixen en valor amb els del vector v_C. Volem fer el mateix algorisme de

de shorts sobre una variablesuma_java de tipus short . Modifiqueu el necessari per

implementar l’algorisme de la figura 2.11.

Comproveu que el resultat obtingut és el mateix que en el primer apartat de l’exercici 2.

Un cop us funcioni, anem a introduir una sentènciaif-else. Copieu el fitxer TDMA3.ASM a

TDMA4.ASM i modifiqueu-lo per implementar el codi de la figura 2.12.

Comprovació: Els elements del vector són: 1, 2, 300, 123, -45, 23, -62, -13. Per tant heu de

quins valors tindran les variablessuma_pos i suma_neg al final de la execució.

short v_JAVA[]= new short[8];short suma_java;

suma_java=0;for (int i=0; i<8; i++)

{ suma_java += v_JAVA[i];}

figura 2.11: Sumatori de tots els elements d’un vector Java.

short v_JAVA[]= new short[8];short suma_pos;short suma_neg

for (int i=0; i<8; i++){ if (v_JAVA[i]<0){

suma_neg += v_JAVA[i];}

else {suma_pos += v_JAVA[i];}

}

figura 2.12: Codi amb una sentènciaif-else bàsica.

33

Page 35: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

2.14).

Activitat 2.C: Accés a matrius tipus C

El fitxer TDMA5.ASM (que ja existeix) conté el que es pot veure a la figura 2.13.

En aquest fitxer està definida una matriu tipus C anomenadamat_c . És una matriu de 4 files

per 6 columnes (int mat_c[4][6]; ) que ja està inicialitzada. Resoleu l’exercici 2.2.

Volem fer un programa que sumi tots els elements de la columna 2 de la matriu (figura

.dataaux0 dd 6 dd 0,1,2,3,4,5aux3 dd 6 dd 30h,31h,32h,33h,34h,35haux2 dd 6 dd 20h,21h,22h,23h,24h,25haux1 dd 6 dd 10h,11h,12h,13h,14h,15haux_j dd 4 dd aux0 dd aux1 dd aux2 dd aux3mat_java dd aux_jmat_c dd 0,1,2,3,4,5 dd 10h,11h,12h,13h,14h,15h dd 20h,21h,22h,23h,24h,25h dd 30h,31h,32h,33h,34h,35hsuma_java dd 0suma_c dd 0.code.startup

.exitEND

figura 2.13: Fitxer TDMA5.ASM

exercici 2.2

Donada la definicióint mat_c[4][6]; com a matriu de tipus C, suposant quei és una variable int, quina és la fórmula per accedir a l’element mat_c[i][2]?

34

Page 36: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

ercici

lement

la

(104

Implementeu aquest codi utilitzant per a l’accés de dins del bucle la fórmula trobada a l’ex

2.2 (accés aleatori). Per comprovar-ho, el resultat és 104 = 0x68.

Sabem que també es pot fer accés seqüencial (trobar un element en funció de l’e

anterior). Feu l’exercici 2.3.

Copieu el fitxer TDMA5.ASM a TDMA6.ASM i implementeu sobre aquest últim el codi de

figura 2.14 amb accés seqüencial. Utilitzeu el resultat de l’exercici 2.3. El resultat és el mateix

= 0x68).

suma_c=0;for (int i=0;i<4;i++)

{suma_c += mat_c[i][2];}

figura 2.14: Suma dels elements de la columna 2.

exercici 2.3

Calculeu les fórmules de l’accés a mat_c[i][2] i mat_c[i+1][2] i trobeu la diferència

35

Page 37: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

da

Activitat 2.D: Accés a un vector de vectors (Java).

Copieu el fitxer TDMA5.ASM a TDMA7.ASM. Observareu (figura 2.13) que tenim defini

la mateixa matriu amb els mateixos valors com a vector de vectors de Java (mat_java ). Volem que

implementeu el codi de la figura 2.15.

Ho haureu d’implementar per mitjà d’accés aleatori. Feu l’exercici 2.4.

Implementeu l’algorisme i comproveu el resultat (novament dóna 104 = 0x68).

suma_java=0;for (int i=0;i<4;i++)

{suma_java += mat_java[i][2];}

figura 2.15: Suma dels elements de la columna 2.

exercici 2.4

Donada la definicióint mat_java[4][6]; com a matriu de tipus Java,quina és la fórmula que ens permet accedir a l’element mat_java[i][2]?

36

Page 38: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

en les

ducció

Sessió 3: Subrutines

Objectius: En aquesta sessió experimentarem en l’ús de subrutines. Veurem com es realitz

diferents fases de la gestió de les subrutines i programarem subrutines a partir d’una tra

sistemàtica de codi en alt nivell que utilitza funcions i/o procediments.

Lectura prèvia

A continuació trobareu un resum amb els conceptes més importants que s’han introduït en

aquest tema de subrutines: definicions, fases de la seva gestió, contingut del bloc d’activació i

traducció de codi en alt nivell que utilitza funcions i/o procediments.

Definicions

Subrutina: Conjunt d’instruccions de llenguatge màquina (o assemblador) que realitza una

tasca parametritzable. Serveix per implementar les funcions, procediments i mètodes que

existeixen en els llenguatges d’alt nivell.

Vegeu en la figura 3.1 els diferents elements que apareixen en un codi en alt nivell on es

defineix una funció i es referencia aquesta funció.

figura 3.1: Definició i referència d’una funció

...r = f(pr1,pr2);...

int f (int pf1, int pf2){/* variables locals*/l1,l2:int;

(* cos de la funció *)return resultat;

}

❶ activació de la funció

❷ desactivació de la funció

pr1,pr2: paràmetres realspf1, pf2: paràmetres formalsr: resultat de la funciól1,l2: variables locals

37

Page 39: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

Bloc d’activació: Correspon a tota la informació que es manega durant la gestió de les

subrutines: resultat de la subrutina, paràmetres de la subrutina, adreça de retorn, variables locals i

estat del processador. La major part del bloc d’activació es guarda a la pila (excepte el resultat i

aquelles variables locals que s’emmagatzemen en registres).

Paràmetres reals/formals:Els paràmetres reals són els que es passen en cadascuna de les

activacions que es fan a una subrutina. Els paràmetres formals són els que s’utilitzen dins la

definició d’una subrutina.

Paràmetres per valor/ per referència:Un paràmetre per valor és únicament d’entrada a una

subrutina. Un paràmetre per referència pot ser d’entrada i/o sortida.

Fases de la gestió de les subrutines

Passar els paràmetres:Consisteix en col.locar els paràmetres reals que es passen a un

subrutina en el lloc adequat perquè la subrutina pugui utilitzar-los quan necessiti accedir als seus

paràmetres formals.

Considerarem que els paràmetres sempre es passen en la pila. L’ordre en què s’empilen els

paràmetres sempre és el contrari a l’ordre en què estan escrits.

Un paràmetre per valor es passa col.locant una CÒPIA del paràmetre real en el cim de la pila.

Un paràmetre per referència es passa col.locant l’ ADREÇA del paràmetre real en el cim de la pila.

Cridar a la subrutina: Consisteix en guardar l’adreça de retorn a la pila i saltar a executar la

primera instrucció de la subrutina. Tot això es fa quan s’executa la instrucció CALL.

Establir el punter al bloc d’activació (o establir l’enllaç dinàmic):Consisteix en inicialitzar

un registre (s’utilitza el “Frame Pointer” o EBP) perquè apunti a una posició fixa dins el bloc

d’activació.

Crear les variables locals.Consisteix en reservar a la pila l’espai necessari per a les

variables locals a la subrutina i, si cal, inicialitzar-les. L’ordre en què queden les variables locals a la

pila és el mateix amb el que han estat declarades.

Salvar l’estat:Consisteix en guardar a la pila tots els registres que es modifiquen en el cos de

la subrutina.

Executar la subrutina:Els aspectes específics a nivell de subrutines que es poden produir

en el cos de la subrutina i que hem de saber realitzar correctament són: accés als paràmetres,

accés a les variables locals i accés al resultat.

A un paràmetre s’hi accedeix a través del registre EBP amb el desplaçament positiu

necessari segons el lloc que li correspon dins el bloc d’activació. A una variable local s’hi accedeix

a través del registre EBP amb el desplaçament negatiu adequat. El resultat d’una subrutina sempre

es col.loca en el registre EAX (o bé en l’AX o l’AL si la mida del resultat fos de 2 o d’1 byte).

38

Page 40: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

Restaurar l’estat: Consisteix en recuperar el valor que tenien els registres que s’hagin

modificat al llarg de la subrutina.

Eliminar les variables locals:Consisteix en alliberar l’espai que ocupaven les variables locals

dins la pila.

Restaurar el punter al bloc d’activació:Consisteix en recuperar el valor del registre EBP que

hi havia a l’inici de la subrutina.

Retornar de la subrutina:Consisteix en saltar a la instrucció següent a la de la crida a la

subrutina. Això es fa quan s’executa la instrucció RET.

Eliminar els paràmetres:Consisteix en treure de la pila tots els paràmetres que s’hagin

passat.

Recollir el resultat:Consisteix en agafar el resultat que ha deixat la subrutina en el registre

EAX (o bé en l’AX o en l’AL, segons la seva mida).

Traducció literal de codi en alt nivell

A continuació repassarem quina és la traducció a llenguatge assemblador que resulta d’un

codi en alt nivell que defineix una funció i la referencia. Vegeu aquest codi en la figura 3.2.

En aquest exemple veiem que es defineix una funció f que té dos paràmetres d’entrada i

retorna un enter. El paràmetre formal pf2 és un enter i per tant es passa per valor. El paràmetre

formal pf1 és un vector i es passa per referència. En el programa principal es fa una referència a la

funció on es passen com a paràmetres reals les variables globals pr1 i pr2 . El resultat de la funció

es guarda a la variable global r .

figura 3.2: Exemple de codi en alt nivell que utilitza funcions

int r,pr1[10],pr2; // pr1 és un vector C

int f(int pf1[10], int pf2) { // pf1 és un vector Cint l1,l2;

l1 = pf1[0];l2 = pf2;return (l1+l2)/2;

}

void main() {r = f(pr1,pr2);

}

39

Page 41: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

A l’hora de traduir aquest codi és recomanable que tinguem clarament identificat quin és el

contingut del bloc d’activació que es formarà a la pila. Adoneu-vos que el bloc d’activació està

totalment construït en el moment que s’ha acabat d’executar la fase anomenada “Salvar l’estat” i,

per tant, estem a punt de començar a executar el cos de la subrutina. La figura 3.3 mostra el

contingut del bloc de l’activació de la subrutina que estem considerant en aquest exemple.

La traducció literal (sense optimitzar) d’aquest codi a assemblador seria el que es mostra a la

figura 3.4. Observeu que les subrutines es col.loquen en el segment de codi abans que comenci el

programa principal (abans de la directiva .startup ).

Abans de començar a fer les diferents parts de la pràctica mireu com s’han implementat les

diferents fases de la gestió de subrutines i com s’ha traduït literalment cadascuna de les sentències

que hi ha en el cos de la subrutina exemple.

figura 3.3: Contingut del bloc d’activació abans de començar el cos de la subrutina

PF2@PF1

@retorn

EBPantSS:EBP

L2

L1

reg1

...

El punter al paràmetre PF1 és a l’adreça: SS:8[EBP]

El paràmetre PF2 és a l’adreça: SS:12[EBP]

La variable local L1 és a l’adreça: SS:-8[EBP]

La variable local L2 és a l’adreça: SS:-4[EBP]

regn

40

Page 42: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

figura 3.4: Exemple de codi en assemblador que utilitza subrutines

.model large

.386

.stack 100h

.dataPR1 DD ?PR2 DD ?R DD ?

.code

F PROCPUSH EBP ; establir punter ...MOV EBP, ESP ; ... al bloc d’activacióSUB ESP, 8 ; crear variables localsPUSH ES ; salvar ...PUSH EBX ; ... l’estat

; COS DE LA SUBRUTINA (INICI)MOV ES, 10[EBP] ; traducció de ...MOVZX EBX, WORD PTR 8[EBP] ; ...MOV EBX, ES:[EBX] ; ...MOV -8[EBP], EBX ; ... l1 := pf1[0]

MOV EBX, 12[EBP] ; traducció de ...MOV -4[EBP], EBX ; ... l2 := pf2

MOV EBX, -8[EBP] ; traducció de ...ADD EBX, -4[EBP] ; ...SAR EBX, 1 ; ...MOV EAX, EBX ; ... retorna (l1+l2)/2

; COS DE LA SUBRUTINA (FI)

POP EBX ; restaurar ...POP ES ; ... l’estatMOV ESP, EBP ; eliminar variables localsPOP EBP ; restaurar punter al bloc d’act.RET ; retornar de la subrutina

F ENDP

.startupPUSH PR2 ; passar paràm. per valorPUSH DS ; passar ...LEA AX, PR1 ; ...PUSH AX ; ... paràm. per referènciaCALL F ; cridar la subrutinaADD ESP, 8 ; eliminar els paràmetresMOV R, EAX ; recollir el resultat.exit

end

41

Page 43: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

eu el

ma els

ció per

es, que

passen

e

Enunciats de la sessió

Activitat 3.A: Veure el bloc d’activació

La primera activitat consisteix en veurem com és un bloc d’activació concret. Consider

codi en alt nivell que apareix a la figura 3.5. En aquest programa es defineix una funció que su

elements d’un vector (emmagatzemat per files com en C) i es fa una referència a aquesta fun

calcular la suma dels elements del vectort .

Tindrem en compte les consideracions per defecte que es fan durant la gestió de subrutin

són:

• Els paràmetres es passen en la pila de dreta a esquerra.

• El pas de paràmetres de tipus basics es fa sempre per valor mentre que els vectors es

per referència.

• El resultat es retorna en el registre EAX.

• Les variables locals s’emmagatzemen a la pila. En aquest cas concret, només s’ha d

guardar a la pila la variabletmp , ja que la variablei , que és de control d’un bucleper , es

guarda en un registre directament.

Feu l’exercici 3.1.

figura 3.5: Codi en alt nivell considerat en l’activitat 1

// constantsfinal int N=5;// variables globalsint res;int t[N]={10,11,12,13,14};

int suma_vector(int v[N], int num) {int tmp;

tmp = 0;for (int i=0; i<num; i++) {

tmp += v[i];}return tmp;

}

void main() {res = suma_vector(t,N);

}

42

Page 44: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

. Per

figura

ar-lo.

pte la

tot el

rucció

ueix

b F8 i

de codi

s

c

de la

s

anera

servir

de la

ut de

Anem a comprovar amb el TurboDebugger quin és el contingut d’aquest bloc d’activació

a això, utilitzarem el programa SUBR1.ASM, que és la traducció a assemblador del codi de la

3.5.

Primer de tot, hauríeu d’entendre el codi de la subrutinasuma_vector . És un exercici de

traducció literal de subrutines, i es fa tal com s’ha resumit en la lectura prèvia.

Un cop analitzat el programa, l’assembleu i el munteu per tenir-lo preparat per a depur

Dins el TD, el primer que heu de fer és comprovar que l’execució és correcta. Tenint en com

inicialització del vectort , el contingut final de la variableres ha de ser0000003Ch .

És convenient que sapigueu una opció més que ens permet el TD. A part d’executar

programa sencer (F9), executar fins un punt d’aturada (F2 + F9) o executar instrucció a inst

(Trace , F7), hi ha la possibilitat d’executar tot el codi de la subrutina de cop. Això s’aconseg

amb l’opcióStep (la seva tecla de funció associada és F8). Proveu d’executar el programa am

amb F7 i observeu les diferències que hi ha. Mentre ho feu, adoneu-vos que a la subfinestra

de la CPU, quan hi ha una instrucció “CALL”, apareix també una instrucció “PUSH CS” prèviament.

Això és correcte. Quan programeu en assemblador una instruccióCALL es posen sempre aqueste

dues instruccions en llenguatge màquina.

Un cop vista la diferència entreStep i Trace anem a veure el bloc d’activació. El blo

d’activació està totalment constituït quan comencem a executar la primera instrucció del cos

subrutina (MOV ES, 10[EBP]). Polseu, doncs, la teclaF7 (Trace) cinc cops perquè s’executin le

instruccions anteriors a aquesta. Sabem que el bloc d’activació està a la pila, però la millor m

de visualitzar-lo no és a través de la subfinestra de la pila (dins la finestra CPU). El millor és fer

la subfinestra de memòria, ja que és molt més flexible d’utilitzar. Us situeu en aquesta part

finestra CPU i li indiqueu que voleu visualitzar a partir de l’adreça SS:EBP (premeuCTRL-G per

poder introduir l’expressió de l’adreça a visualitzar). Indiqueu també que voleu veure el conting

exercici 3.1

Escriviu els elements que constitueixen el bloc d’activació de la subrutina

suma_vector . A l’esquerra, indiqueu el desplaçament, relatiu al EBP, de cada element

SS: EBP+( )

SS: EBP+( )SS: EBP+( )SS: EBP+( )SS: EBP+( )

@lògica element del bloc d’activació

43

Page 45: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

ó

dades.

BP+0 hi

, que

cimal.

on

na

splaceu

tingut

bloc

d’una

oincidir

l al que

funció

memòria en mida dword (premeuCTRL-D Long ). Llavors, veureu el contingut del bloc d’activaci

que hi ha a partir d’on apunta EBP.

Observeu que el registre de segment de la pila coincideix amb el registre de segment de

Això és degut al tipus de model de programació que considerem (.model large ). Per tant, la

subfinestra de dades us posarà DS:0110 i aquesta adreça és la mateixa que SS:EBP. A SS:E

ha d’haver el contingut anterior del registre EBP. A SS:EBP+4 hi ha d’haver l’adreça de retorn

ésCS:006A . A SS:EBP+8 hi ha d’haver el punter al paràmetrev , que ésDS:0004 . A SS:EBP+12

hi ha d’haver el paràmetrenum, que és00000005 .

És important que sapigueu que el TD interpreta tots els números que introduïu en hexade

Així, si volguéssiu anar a veure el paràmetrenum directament (que està 12 bytes més enllà d’

apunta EBP), hauríeu de prémerCTRL-G seguit de SS:EBP+0C dins la finestra on us dema

l’expressió.

Si voleu veure el contingut de les adreces anteriors a on apunta EBP només cal que us de

amb el cursor o li indiqueu que voleu veure a partir d’una altra adreça. Així, si voleu veure el con

de la variable localtmp , us posicioneu a SS:EBP-4.

La figura 3.6 us mostra el contingut sencer del bloc d’activació. El rang d’adreces del

d’activació és [SS:0102, SS:011F]. Tingueu en compte que el valor dels segments pot variar

execució a una altra. Per tant, els valors dels segments que surten a la figura no tenen per què c

amb els que obteniu vosaltres. Per exemple, en l’adreça de retorn, el segment ha de ser igua

valgui el registre CS. D’altra banda, el contingut de la variable localtmp és indefinit ja que encara

no s’ha inicialitzat. Tingueu en compte també que el contingut dels registres podria variar en

de com estiguin inicialitzats al principi del programa.

ds:0100 5BDA.... 00000000ds:0108 00000020 xxxxxxxxds:0110 00000000 5BEA006Ads:0118 5BF20004 00000005ds:0120 ........ ........

figura 3.6: Contingut del bloc d’activació

ES

CSDS

SS=DS

44

Page 46: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

iment

conté

cució.

ioni

un

hi ha

er per

us

ut del

Activitat 3.B: Analitzar una subrutina (que conté errors)

Haureu d’analitzar el codi d’una subrutina que correspon a la traducció literal del proced

que es mostra a la figura 3.7. El codi de la subrutina és a la figura 3.8. Tanmateix, la subrutina

uns quants errors. Els errors es produeixen tant en temps d’assemblatge com en temps d’exe

L’objectiu és que localitzeu tots els errors i aneu corregint la subrutina fins que func

correctament.

El procés que hauríeu de seguir és el següent:

• Fer l’exercici 3.2. Es tracta de dibuixar el bloc d’activació corresponent asubr2 .

• Fer un seguiment visual del codi de la subrutinasubr2 . Mireu si hi ha algun error que ja el

pogueu localitzar directament. Aneu escrivint els errors en el lloc estipulat en l’exercici 3.3.

• Assemblar el programa. El codi de la subrutina és al fitxer SUBR2.ASM. Veureu que hi ha

error d’assemblatge en el codi original. Esbrineu què és el que es pretén fer en la línia que

l’error i programeu-ho adequadament.

• Depurar el programa. Aquí es tracta que utilitzeu les eines que us ofereix el Turbo Debugg

fer la depuració dels programes. Heu de considerar el programa principal (figura 3.7) que

donem fet i que NO CONTÉ CAP ERROR (no l’heu de modificar).

Per saber si teniu la subrutina programada correctament, heu de visualitzar el conting

vectorvs, situant-vos a la subfinestra de dades i prementCTRL-G seguit devs . La subrutina el

que fa és col.locar envs[i] el valor del primer paràmetre (ve[i] ) mes el segon (-3 ). Per tant, com

que el vectorve està inicialitzat a (-1,0,1,2,3,4) el contingut correcte del vectorvs al final del

programa hauria de ser: (-4, -3, -2, -1, 0, 1).

figura 3.7: Programa principal que referencia el procediment SUBR2

// variables globalsint ve[6]={-1, 0, 1, 2, 3, 4};int vs[6];

void subr2(int a, int b, int c, int v[6]) {}

void main() {int i;

for (i=0; i<6; i++) {subr2(ve[i], -3, i, vs);

}}

45

Page 47: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

figura 3.8: Codi del procediment considerat en l’activitat 2.B

void subr2( int a, int b, int c,int v[6]) {

int loc;

loc = a + b;v[c] = loc;

}

exercici 3.2

Dibuixeu el bloc d’activaciód’aquest procediment

figura 3.9: Subrutina que conté errors

SUBR2 PROC

PUSH EBPMOV EBP, ESPSUB ESP, 4PUSH EAXPUSH EBXPUSH ES

MOV ECX, 4[EBP]ADD ECX, 6[EBP]MOV EBX, WORD PTR 20[EBP]MOV ES, 22[EBP]MOV EAX, 12[EBP]MOV ES:[EBX+4*EAX], ECX

POP EAXPOP EBXPOP ESMOV ESP, EBPPOP EBP

SUBR2 ENDP

exercici 3.3

Anoteu els errors que aneulocalitzant i com els heu corregit.

46

Page 48: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

es reals.

la

a de

ments

r

, com

l byte de

r és

i ha

Activitat 3.C: Implementar diversos passos de paràmetres

En aquesta activitat farem el pas de paràmetres per diferents tipus de dades i de paràmetr

A la figura 3.10 es mostra l’estructura del programa i la definició de variables globals.

El programa principal crida a la funciósubr3 i li passa per paràmetre el valor 0. Aleshores

subrutinasubr3 fa una crida a la funciós3 i li passa:

M - variable global de tipus matriu C (per referència)

tam_fila - variable local de tipus enter (per valor)

param - paràmetre de tipus enter (per valor)

V - variable local de tipus vector C (per referència)

‘X’ - constant de tipus char (per valor)

La funciós3 es una funció externa, és a dir, no està definida al mateix fitxer font, pero s’h

muntar junt amb aquest programa per construir l’executable. Aquesta funció copia tots els ele

vectorv2 a la filanfila de la matriuv1 i retorna el número de vegades que ha trobat el caràctec.

Feu en primer lloc l’exercici 3.4. Tingueu en compte que els les dades que ocupen 1 byte

ara els caràcters, quan es passen com a paràmetre ocupen 2 bytes a la pila i la dada està a

menys pes (el de més pes no conté informació útil).

Després comproveu amb el TD que el codi sigui correcte. El fitxer que heu d’utilitza

SUBR3.ASM. La funciós3, ja assemblada, és al fitxer S3.OBJ. Comproveu com al programa h

figura 3.10: Estructura del programa

// definicio variables globalschar M[2][7]={‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’,

‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’ };

int res;

// definicio subrutina externaint s3( char v1[2][7], int tam, int nfila, char v2[7], char c) {}

// subrutina a programarint subr3(int param){

char V[7] = {‘D’, ‘I’, ‘A’, ‘0’, ‘D’, ‘I’, ‘A’};int ret, tam_fila = 7;

ret = s3 (M, tam_fila, param, V, ‘D’);return ret;

}

// programa principalvoid main () {

res = subr3(0);}

47

Page 49: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

i

ar la

una directiva .extrn s3:far per tal d’indicar que el símbols3 correspon a una etiqueta de cod

que es defineix externament. La comanda per muntar el programa ha de ser:

tlink /3/v subr3 s3

Al fitxer SUBR3.ASM només hi heu d’afagir les instruccions necessàries per implement

subrutinasubr3: salvar i restaurar els registres utilitzats, fer el pas de paràmetres abans delcall ,

alliberar l’espai dels paràmetres després delcall i retornar el valorret .

Els resultats correcte que hi hauria d’haver a les variables globals són:

res = 00000002h

M = ‘DIA0DIA’

exercici 3.4

SS: EBP+( )

SS: EBP+( )SS: EBP+( )SS: EBP+( )SS: EBP+( )

@lògica elements del bloc d’activació

SS: EBP+( )

SS: EBP+( )SS: EBP+( )SS: EBP+( )SS: EBP+( )

Dibuixeu el bloc d’activació desubr3 i calculeu l’adreça deV respecte elEBP

@V=

Programeu les instruccions necessàries per fer el pas de paràmetres enret = s3 (M, tam_fila, param, V, ‘D’);

48

Page 50: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

ue és

n índex

que els

.

a la

Activitat 3.D: Programar una subrutina sencera

En aquest darrera activitat heu de programar una subrutina recursiva i comprovar q

correcte. És la subrutinasubr4 que hi ha dins el programa de la figura 3.11.

El que fa aquesta subrutina és calcular el producte dels elements d’un vector que tenen u

comprès dins el rang establert per [i..j] (i,j són paràmetres de la funció). Es considera sempre

vectors començen amb l’índex 0, estan emmagatzemats com en C i es passen per referència

El programa principal ja el teniu codificat dins el fitxer SUBR4.ASM. Fa dues crides

subrutinasubr4 . La primera serveix per calcular el producte de tots els elements del vectorA. El

resultat ha de ser 144 (en decimal). La segona calcula el producte dels elementsB[2] a B[5] . El

resultat ha de ser -4.

Feu l’exercici 3.5.

figura 3.11: Programa considerar en l’activitat 4

// programa recursiufinal int N = 10;

int A[N] = {-2, -2, -1, -1, 1, 1, 2, 2, 3, 3};int B[N] = {1, 1, 1, 2, -1, 2, 3, 3, 3, 3};int res1,res2;

int subr4(int v[N], int i, int j) {int loc;

if (i==j) {loc = v[i];

} else {loc = v[i] * subr4(v,i+1,j);

}return loc;

}

void main() { res1 = subr4(A,0,N-1); res2 = subr4(B,2,5);}

exercici 3.5

Passeu a fer la programació de la subrutina dins el fitxer SUBR4.ASM icomproveu el resultat

49

Page 51: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

. Poseu

de

ent a

Activitat Opcional: Mida de la pila

Feu els següents exercicis:

Determineu quina és la mida en bytes que es necessita per a la pila en el vostre programa

un punt d’aturada dins el cos de la subrutinasubr4 i aneu executant. Fixeu-vos en la diferència

valors del registre ESP entre el principi del programa i l’última activació que es faci correspon

la primera crida asubr4 del programa principal.

exercici 3.6

Contesteu a les següents preguntes:

• On assignareu la variable localloc ? A la pila o a un registre?:• Quants bytes ocuparà un bloc d’activació desubr4 ?:

(no compteu l’estat; no sabeu el que ocupa abans de programar)• Quin és el nombre màxim de blocs d’activació que hi haurà a la

pila per la primera crida que es fa dins el programa principal?• I per la segona crida?• Quants bytes hauria de tenir la pila per assegurar que no

es produeixi sobreeiximent?(hauríeu de considerar un marge de seguretat per a l’estat)

exercici 3.7

Poseu en la definició de la pila la mida que hagueu considerat convenient en l’exercicianterior.

exercici 3.8

Contesteu a la següent pregunta:

• Quants bytes han ocupat tots els blocs d’activació que hi ha hagutsimultàniament a la pila durant l’execució d’aquest programa?

50

Page 52: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

a

isme

tecle-

Sessió 4: E/S per enquest

Objectius: Aprendre a escriure directament a la pantalla de l’IBM PC. Entendre el mecan

bàsic de sincronització per enquesta i construir programes senzills per llegir els caràcters

jats al PC.

Lectura prèvia

Us expliquem a continuació els aspectes bàsics del funcionament de la pantalla i del

teclat a l’IBM PC. Tots aquests aspectes seran importants en el desenvolupament de la sessió.

Per tenir una descripció més detallada d’aquests dispositius podeu consultar el document

“Descripció dels dispositius d’E/S en l’IBM PC”, d’Eduard Ayguadé, Agustín Fernández i

Antonio González, publicat pel CPET.

La pantalla de l’IBM PC

La pantalla en mode text es pot veure com una matriu de tipus C, amb 25 files (de la fila

0 a la 24) x 80 columnes (de la columna 0 a la 79). El controlador que governa la pantalla té

dos registres de 8 bits per cadascuna de les posicions de la pantalla. El processador ha

d’escriure en aquests registres la informació que vol que es vegi a la pantalla, tal i com

s’explica més endavant. Podem considerar doncs que el controlador té 25x80x2 registres de

dades. No té cap registre de estat ni de control.

La figura 4.1 mostra la correspondència entre els registres de dades del controlador i les

posicions de la pantalla. Els registres 0 i 1 corresponen a la posició (0,0) de la pantalla. Si

volem escriure un caràcter en aquesta posició llavors escriurem el codi ASCII del caràcter al

registre 0 i l’atribut al registre 1. L’atribut és un codi de 8 bits que indica la forma com s’ha de

visualitzar el caràcter. Els atributs que utilitzarem són:

00000111b 07h normal:fons negre,caràcter blanc

01110000b 70h invers:fons blanc,caràcter negre

Després d’escriure el codi ASCII i l’atribut als registres 0 i 1, el caràcter es veurà a la

posició (0,0) de la pantalla mentre no modifiquem el contingut d’aquests registres.

Cadascuna de les posicions de pantalla restants tenen associats un parell de registres,

amb una correspondència per files. És a dir, els registres 2 i 3 estan associats a la posició (0,1),

51

Page 53: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

els registres 4 i 5 a la posició (0,2) i, en general, el registre (80*i+j)*2 conté el codi ASCII del

caràcter que s’ha de veure a la posició (i,j) i el registre (80*i+j)*2 + 1 conté l’atribut.

Els registres del controlador de pantalla estan mapejats a l’espai de memòria, a partir

d’una adreça que anomenem adreça base. Aquesta adreça base depèn de la tarjeta gràfica

què disposi el PC. En alguns PCs l’adreça base física és B0000h (l’adreça base lògica és

0B000h:0000 ). En altres PCs l’adreça base física és B8000h (l’adreça base lògica és

0B800h:0000 ). Quan el sistema operatiu DOS fa el boot, inicialitza una variable amb el mode

de vídeo de la tarjeta. En concret, el valor del byte de l’adreça de memòria 0000:0449h conté

informació sobre la tarjeta. Si el valor d’aquest byte és 7, l’adreça base és 0B0000h . Si el valor

és 2 o 3, llavors l’adreça és 0B8000h .

Vosaltres disposeu d’una rutina que consulta el byte de l’adreça de memòria

0000:0449h . La rutina es diu ADPANT, i retorna pel registre AX el valor del número de

segment on està mapejada la pantalla (0B000h o 0B800h ). El següent fragment de codi, per

exemple, escriu el caràcter ‘A’ , en mode normal, a la posició (0,0) de la pantalla.

0,00

1

24

i

0 1 79j

0,1

1,0 1,1

0,2 0,79

i,j

24,7924,0

0,0

0,1

0,2

0,79

1,0

1,1

i,j

24,79

0

(80*i+j)*2

123

158159

(80*i+j)*2+1

Registres del Controlador de Pantalla Posicions de la Pantalla

Codi ASCII del caràcter de la posició (0,0)

Atribut del caràcter de la posició (0,0)

figura 4.1: Correspondència entre els registres del controlador de la pantalla i les

posicions de la pantalla

52

Page 54: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

CALL ADPANT ; deixa en AX el número de segment; de l’adreça base de pantalla

MOV ES, AX ;MOV ES:0,BYTE PTR ‘A’ ; escrivim el codi ASCII de la ‘A’

; al registre 0(desplaçament 0;respecte del segment que hi ha a ES)

MOV ES:1,BYTE PTR 07h ; escrivim l’atribut al registre 1

Per poder utilitzar la rutina ADPANT, els vostres programes han de declarar-la, abans de

la directiva .stack , de la següent manera:

extrn adpant: far

A més a més, haureu de muntar el vostre programa amb la comanda:

tlink /v/3 nom_fitxer,,,w:ourlib\libio.lib

53

Page 55: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

El teclat de l’IBM PC

Amb un teclat qualsevol es poden fer dos tipus d’accions: polsar una tecla o deixar-la

anar. Quan polsem una tecla diem que s’ha produït un event de tipus MAKE. Quan deixem anar

una tecla diem que s’ha produït un event de tipus BREAK.

El controlador del teclat de l’IBM PC té dos registres de 8 bits cadascun: registre de

dades i registre d’estat (no té registre de control).

El registre d’estat ens indica quan s’ha produït un event. Concretament, quan es

produeix un event (MAKE o BREAK) el bit 0 del registre d’estat es posa a 1.

El registre de dades conté la informació necessària per identificar l’event que s’ha

produït. Tal i com es mostra a la figura 4.2, el bit 7 del registre de dades indica el tipus d’event

(si és 0 llavors és un MAKEi si és 1 llavors és un BREAK). Els 7 bits baixos del registre de dades

contenen el codi de rastreig. Aquest codi és un número que ens permet identificar la tecla que

s’ha polsat o que s’ha deixat anar. Cada tecla té associada un codi de rastreig diferent, d’acord

amb l’esquema que es mostra a la figura 4.3.

Per saber quin és el codi ASCII corresponent a un codi de rastreig determinat teniu a la

biblioteca de programes LIBIO.LIB la taula TTECLAT. La manera d’accedir-hi és la següent:

MOV BL, TTECLAT[EAX]

on en EAXheu de tenir el codi de rastreig (el bit de MAKE/BREAKha d’estar a zero) extès

a 32 bits. Aquesta instrucció deixa al registre BL el codi ASCII corresponent al codi de rastreig

CODIM/B

0: MAKE1: BREAK

figura 4.2: Configuració del registre de dades del teclat

1 59 60 61 62 63 64 6665 67 68 87 88 70. .

82 71 73

83 79 81

80

72

75 77

69 53 55 74

71 72 73

75 76 7778

79 80 81

82 8328

41 2 3 4 5 6 7 8 9 10 11 12 13 14

15 16 17 18 19 20 21 22 23 24

58 30 31 32 33 34 35 36 37 38

42

29

86 44 45 46 47

56

48 49 50 51

57

25 26 27

39 40 43

52 53

56 29

54

28

figura 4.3: Codi de rastreig associat a cadascuna de les tecles del teclat

54

Page 56: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

que hi hagi en EAX. En cas de ser un caràcter, el codi que queda és el del caràcter EN

MAJÚSCULES.

Per poder fer servir la taula TTECLAT, l’heu de declarar, abans de la directiva .stack ,

de la següent manera:

extrn tteclat: byte

A més a més, haureu de muntar el vostre programa amb la comanda:

tlink /v/3 nom_fitxer,,,w:ourlib\libio.lib

Els registres del controlador de teclat estan mapejats a l’espai d’entrada/sortida.

Concretament, el registre d’estat és a l’adreça 64h i el de dades és a l’adreça 60h . Per

tant, aquests registres s’han de llegir amb la instrucció IN . Quan es llegeix el registre de dades,

el bit baix del registre d’estat es posa a 0 automàticament.

En general, per llegir el teclat per enquesta cal seguir els següents passos:

1 Inhibir les interrupcions del teclat (veure més endavant).

2 Consultar de forma contínua el registre d’estat fins que el bit 0 es posi a 1,

indicant que s’ha produït un event (MAKE o BREAK).

3 Llegir el registre de dades per determinar l’event que s’ha produït (això farà que

baixi el bit 0 del registre d’estat).

4 Determinar si l’event és un MAKE o un BREAK.

5 Obtenir, a partir del codi de rastreig, el codi ASCII corresponent a la tecla. En

aquest pas es farà servir la taula TTECLAT.

6 Restaurar les interrupcions del teclat.

Com hem vist abans, el teclat no té registre de control, que seria el lloc natural per inhibir

les interrupcions del teclat. Aquesta inhibició s’ha de fer directament al controlador

d’interrupcions, que s’explicarà en detall a la sessió 5. De moment, és suficient saber que per

inhibir les interrupcions del teclat s’ha de posar a 1 el bit 1 del registre de màscara del

controlador d’interrupcions. Aquest registre està mapejat a l’adreça 21h de l’espai d’entrada/

sortida. Per tant, el codi necessari per inhibir les interrupcions del teclat és:

CLIIN AL,21hOR AL,00000010bOUT 21h,ALSTIPer restaurar les interrupcions del teclat, s’ha de tornar a deixar un 0 al bit 1 del registre

de màscara.

55

Page 57: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

e cada

e diu

manda

’ en

Enunciats de la pràctica

Consideracions generals

Tots els exercicis d’aquesta sessió escriuen alguna cosa a la pantalla. La prova qu

exercici està resolt correctament es fa comprovant que a la pantalla s’escriu el qu

l’enunciat. Per tant, no s’ha de fer servir el TD.

Abans d’executar cadascun dels programes d’aquesta sessió, s’ha d’executar la co

CLS del DOS. Aquesta comanda posarà la pantalla en blanc.

No us oblideu que els programes s’han de muntar amb la comanda:

tlink /v/3 nom_fitxer,,,w:ourlib\libio.lib

Activitat 4.A: Escriptures a la Pantalla

El fitxer ENQ1.ASM només conté les següents instruccions:

CALL ADPANT

MOV ES,AX

MOV ES:0,’A’

MOV ES:2,07H

Aquestes instruccions pretenen escriure a la posició [0,0] de la pantalla la lletra ‘A

mode normal.

exercici 4.1

Poseu a punt aquest codi, fent que funcioni tal i com s’espera. Anoteu acontinuació tots els errors que tenia el codi original (tant d’assemblatge comd’execució).

56

Page 58: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

exercici 4.2

Feu una segona versió del codi que faci exactament el mateix que el del’exercici 4.1, però que només tingui tres instruccions. Anoteu a continuacióles tres instruccions.

exercici 4.3

Escriviu a continuació les instruccions necessàries per escriure a la posició[5,7] de la pantalla la lletra ‘A’ en mode invers. Afegiu el codi al programa icomproveu si funciona.

exercici 4.4

Escriviu a continuació les instruccions necessàries per escriure la lletra ‘A’en mode normal en totes les posicions de la pantalla entre la [5,7] i la [6,7](ambdues incloses). Afegiu el codi al programa i comproveu que funciona. Ushauria de sortir un codi amb un bucle amb no més de 4 instruccions.

57

Page 59: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

, s’han

es al

Activitat 4.B: Lectura del teclat per enquesta

En els apartats següents s’ha de treballar amb el teclat per enquesta. Per tant

d’inhibir les interrupcions del teclat, tal i com s’ha explicat a la lectura prèvia, i restaurar-l

final del programa.

Treballarem amb el fitxerENQ2.ASM.

exercici 4.5

Escriviu a continuació el codi necessari per escriure la lletra ‘A’ a la posició[5,7] just en el moment que es produeixi un event de teclat (un MAKE o unBREAK). Incorporeu el codi al programa.

Tanmateix, el programa acaba de seguida. Doneu una explicació d’aquestcomportament.

exercici 4.6

Modifiqueu el codi de l’exercici 4.5 per tal que el caràcter ‘A’ s’escrigui quanes produexi el primer MAKE.

58

Page 60: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

Exercicis opcionals

exercici 4.7

Escriviu a continuació el codi necessari per escriure a la posició [5,7] de lapantalla el primer caràcter teclejat, just en el moment que es produeixi elMAKE. Incorporeu el codi al programa.

exercici 4.8

Feu un programa que escrigui, a partir de la posició [22,7] de la pantalla, totsels caràcters teclejats (en el moment del MAKE). El programa ha d’acabarquan es teclegi la lletra ‘F’.

exercici 4.9

Feu una versió del codi de l’exercici 4.8, en un altre fitxer anomenatENQ3.ASM, eliminant la part d’inhibir i desinhibir interrupcions de teclat.Executeu el programa resultant. Descriviu a continuació les diferències entreel comportament d’aquest codi i el de l’exercici 4.8. Si no observeudiferències, passeu al següent apartat.

59

Page 61: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

exercici 4.10

Modifiqueu els codis dels exercicis 4.8 i 4.9 de forma que, abans de ferl’operació d’enquesta del teclat:

enquesta: IN AL, 64h. . .

s’executi un bucle que simplement doni N voltes. Afegiu entre l’etiquetad’enquesta i la lectura del registre d’estat el següent:

enquesta: MOV ECX,Nespera: DEC ECX

JNZ esperaIN AL, 64h...

Compareu el comportament dels dos codis quan N=1 i N=1000. Què passaquan N es fa gran ? Doneu una explicació d’aquest comportament.

exercici 4.11

Feu un programa que escrigui en pantalla el caràcter teclejat, per a cadaevent del teclat que es produeixi. Si és un MAKE, que l’escrigui a partir de laposició [22,7] en mode normal. Si és un BREAK, que l’escrigui a partir de laposició [23,7], en mode invers. El programa ha d’acabar quan es teclegi lalletra ‘F’.

60

Page 62: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

rames

taura-

etc.

Sessió 5: E/S per interrupcions

Objectius: Entendre el mecanisme bàsic de sincronització per interrupcions, a través de prog

senzills que en mostrin el funcionament. Aprendre a escriure correctament la inicialització i res

ció del vector d’interrupcions, la programació d’una rsi, l’ús de les variables de sincronització,

Lectura prèvia

En aquesta sessió aprendrem a fer petits programes en llenguatge assemblador que se

sincronitzen per interrupcions amb els dispositius de rellotge i de teclat, i escriuen els seus resultats

a la pantalla. A continuació trobareu un resum dels punts clau a tenir en compte per a programar

per interrupcions els dispositius del PC. Per a una descripció més detallada d’aquests dispositius

podeu consultar el document “Descripció dels dispositius d’E/S en l’IBM PC” d’Eduard Ayguadé,

Agustín Fernández i Antonio González, publicat pel CPET.

Les interrupcions, i el controlador d’interrupcions

Gestionar la sincronització de l’E/S per interrupcions significa que quan un dispositiu

requereix l’atenció, envia un senyal de petició al processador, provocant que s’interrompi el

programa en execució i passi a executar-se el codi d’una rutina rsi, que és una subrutina específica

per atendre aquesta petició. Així és com funciona normalment el teclat i el rellotge en el PC.

L’IBM PC té un controlador d’interrupcions, l’i8259, encarregat de gestionar les interrupcions

produïdes pels perifèrics del sistema. Bàsicament, aquest controlador rep les peticions

d’interrupció dels perifèrics, decideix en cada instant quina d’elles ha de ser atesa, interromp al

processador, i li envia l’identificador que correspon al dispositiu que ha de ser atès.

Els dispositius generen les peticions d’interrupció activant els senyals IRQx (interruption

request) connectats a l’i8259. Per exemple, el rellotge activa IRQ0, mentre que el teclat activa

IRQ1. El controlador disposa d’un registre de màscara IMR (port 21H) de 8 bits, que permet inhibir

selectivament cada un dels senyals de petició: si el bit i del IMR val 1, les peticions que arribin per

la línia IRQi seran ignorades. Si arriba més d’una petició simultàniament, el controlador selecciona

la més prioritària (número de petició més petit indica prioritat més alta: IRQ0 > IRQ1). A més a més,

aquest controlador és multinivell, de manera que una rsi en curs pot ser interrompuda si arriba una

nova petició d’un altre dispositiu. No obstant, aquesta petició sols serà atesa pel controlador si el

corresponent dispositiu té major prioritat que el dispositiu servit per l’rsi.

Després de detectar el senyal d’interrupció, el processador notifica al controlador que està

disposat a atendre la petició, i el controlador respon enviant-li un identificador id del dispositiu (id=8

61

Page 63: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

en el cas del rellotge, id=9 en el cas del teclat). Llavors, el processador esbrina l’adreça de la rsi

que li correspon consultant el id-èssim element del vector d’interrupcions, el qual es troba ubicat a

l’adreça física 0 de la memòria, i se suposa correctament inicialitzat. Seguidament, el processador

salva a la pila els registres FLAGS, CS i IP, i fa un salt a la rsi (CS:IP pren per valor l’adreça de la

rsi, i el flag IF es posa a 0).

Les rutines de servei d’interrupció (rsi)

Una rsi ha de seguir les normes elementals de programació de subrutines: salvar el valor

anterior de tots els registres que modifiqui, i restaurar-los abans de finalitzar, ja que poden contenir

informació vital per al programa interromput. Però a més, ha de tenir en compte alguns aspectes

addicionals:

• Una rsi no ha de ser invocada amb instruccions CALL, sinó que s’activa en un instant

impredecible, a instàncies d’un event extern. Per tant, tampoc no rep cap paràmetre, ni

per la pila ni per registre.

• En general, en un computador es pot executar més d’un programa al mateix temps, i

llavors una rsi pot interrompre qualsevol d’aquests programes. Per tant, la rsi no coneix

en absolut el significat dels valors dels registres del programa interromput (o almenys

no en té cap garantia). Per tant, les úniques dades que pot manipular són les variables

globals del programa principal que l’ha instal.lat: búffers, comptadors, variables

booleanes de sincronització, etc.

• Just abans de retornar, la rsi ha de notificar-ho al controlador d’interrupcions, per tal que

aquest gestioni correctament les prioritats de les interrupcions multinivell. Això es fa per

mitjà de la comanda eoi (end of interruption). Executar un eoi consisteix a escriure en el

registre de control del controlador d’interrupcions (adreça 20H) el valor 20H (figura 5.1).

• Finalment, per retornar de la rsi cal fer-ho amb una instrucció especial: IRET. Si hem

programat bé la rsi, en aquest punt el cim de la pila hauria de contenir els valors de IP,

CS i FLAGS salvats en el moment de la interrupció (comproveu que desapileu tants

bytes com hàgiu apilat!). La instrucció IRET els restaura, de forma que causarà un salt

al punt on s’havia produït la interrupció.

El teclat

Aquest dispositiu ja s’ha estudiat a la sessió anterior. Sols ens cal afegir que:

• interromp per a qualsevol event, sigui make (polsació) o break (alliberament).

mov al, 20hout 20h, al

figura 5.1: La comanda eoi

62

Page 64: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

• sol.licita les interrupcions activant el senyal IRQ1

• identificador = 9

• la petició es manté activa fins que el processador llegeix el registre de dades del teclat

(adreça 60H). Per tant, convé assegurar-se que dins la rsi de teclat es faci sempre la

lectura d’aquest registre, per tal de desactivar la petició, encara que no ens interessi el

seu contingut, escrivint: in al,60h

El rellotge

L’IBM-PC té tres temporitzadors programables, integrats en el xip i8253, que serveixen per a

diversos propòsits. Estudiarem un d’aquests temporitzadors (TIMER0), que aquí anomenarem

simplement el rellotge (no el confongueu amb el senyal de rellotge que serveix per seqüenciar els

circuits del processador!). Aquest dispositiu no produeix entrades ni sortides de dades. Tan sols

produeix peticions d’interrupció a intervals regulars, per tal que el sistema tingui noció del temps

real transcorregut. Molts dels seus modes de funcionament, així com el període, són programables,

encara que en aquest curs sols considerarem el seu funcionament bàsic, establert per defecte

quan s’engega el sistema MS-DOS, de la següent manera:

• interromp 18.2 vegades per segon, (però podem considerar 18 interrupcions/s)

• sol.licita les interrupcions activant el senyal IRQ0 (és, per tant, el més prioritari).

• identificador = 8

El programa principal

A diferència de l’E/S per enquesta, no hem d’inhibir les interrupcions, com és obvi. Però el

que sí que hem de fer és modificar el vector d’interrupcions.

El vector d’interrupcions de l’IBM-PC és un vector de tipus C, de punters (2 bytes de

desplaçament i 2 de segment) que es troba sempre a partir de l’adreça física de memòria = 0

(adreça lògica 0000:0000). El i-èssim element del vector conté l’adreça (diem que “apunta”) a la rsi

del dispositiu amb identificador = i (ja hem vist que i=8 per al rellotge, i que i=9 per al teclat).

Si volem treballar amb un dispositiu per interrupcions, haurem ja escrit una subrutina rsi

específica per a aquest dispositiu, i llavors cal que modifiquem l’element corresponent del vector

d’interrupcions per tal que apunti a la nostra rutina. Abans de modificar aquest element, no obstant,

és important guardar el valor anterior per tal que el poguem restaurar abans d’acabar el programa.

Suposem, per exemple, que escrivim la rsi anomenada rellotge_meu per al rellotge, i que

hem declarat una variable adr_vella dd ? per a guardar el valor anterior. Llavors, al principi del

programa principal, haurem de modificar el vector com indica la figura 5.2.

Per restaurar el vector d’interrupcions, al final del programa principal, sols cal desfer les

accions del codi anterior (veure figura 5.3).

63

Page 65: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

Fixeu-vos que en el fragment de la figura 5.2 inhibim les interrupcions quan modifiquem el

vector (CLI ), per impedir que es produeixi una interrupció entremig dels dos mov. Si succeís això, el

processador llegiria en el vector una adreça a mig actualitzar, incorrecta. En el fragment de la figura

5.3 en canvi, no cal inhibir les interrupcions ja que modifiquem el vector amb un sol mov.

Inicialització del registre DS dins una rsi

Cada cop que es fa un accés a memòria s’utilitza un registre de segment. Si s’accedeix a les

variables globals s’utilitza el registre DS per defecte. De la mateixa manera que s’ha dit

anteriorment que no es pot pressuposar cap valor dins una rsi dels registres que s’utilitzen en el

programa principal, tampoc s’ha de pressuposar que el registre DS està apuntant al segment de

dades.

Encara que en el programa hi hagi un únic segment de dades, la resta de rsi que té el sistema

operatiu sí que el poden variar per accedir a les seves variables globals. El comportament erroni es

produiria si la nostra rsi interromp una altra rsi del sistema operatiu que ha canviat el valor del

registre DS. Si això succeeix, quan la rsi accedeixi a la variable, estarà usant el desplaçament

correcte però el segment possiblement canviat, provocant el desastre. En el moment de la

interrupció, el processador inicialitza CS i IP amb l’adreça del segment de codi de la rsi, ja que

l’obté del vector d’interrupcions, però en canvi, no pot inicialitzar l’adreça del segment de dades de

la rsi. En general, serà necessari que el valor del segment de dades quedi inclòs en el propi codi,

en forma reubicable. TASM disposa de la directiva @DATA que permet fer això, com en el següent

exemple:

mov ax, @data ;el segment queda codificat com un immediatmov ds, ax ;inicialitzem DS per accedir a memòria

mov ax, 0mov es, ax ; el vector comença en 0000:0000mov eax, es:[8*4] ; salvo l’adreça vellamov adr_vella, eaxlea ax, rellotge_meu ; en ax tinc el desplaçamentcli ; inhibim les interrupcionsmov es:[8*4], ax ; en i*4 guardem el desplaçamentmov es:[8*4+2], cs ; en i*4+2 el segmentsti ; ja podem permetre interrupcions

figura 5.2: Instruccions per inicialitzar el vector d’interrupcions.

mov ax, 0mov es, axmov eax, adr_vellamov es:[8*4], eax

figura 5.3: Instruccions per restaurar el vector d’interrupcions.

64

Page 66: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

cions

aurem

er saber

manda

codis

un

mar un

a difícil

essador

ús del

que el

és la

).

er,

Enunciats de la sessió

En aquesta sessió modificarem el vector d’interrupcions per tal de controlar les interrup

del rellotge i el teclat. Per aquest motiu, no usarem el TD per depurar els programes, sinó que h

d’executar el programa, observar atentament com respon, i interpretar el seu comportament p

on falla. Abans d’executar cadascun dels programes d’aquesta sessió, s’ha d’executar la co

CLS de DOS, per posar la pantalla en blanc.

Al igual que en la sessió anterior, en algunes activitats s’utilitza la taula de traducció de

de rastreigTTECLATi la subrutina per determinar el segment del búffer de pantallaADPANT, les quals

estan definides en un mòdul extern. Per tant, la comanda per muntar cada programa és:

tlink /v/3 nom_fitxer,,,w:ourlib\libio.lib

Activitat 5.A: Modificar el vector d’interrupcions

En aquesta primera Activitat aprendrem a programar el vector d’interrupcions. Volem

programa que s’esperi durant 5 segons i llavors acabi. Segurament podríem pensar a progra

bucle amb el nombre suficient d’iteracions perquè transcorreguessin els 5 segons, però result

calcular el nombre precís d’iteracions, a part que si més tard executem el programa en un proc

més ràpid o més lent, el retard variarà. La manera correcta de programar un retard fix és fer

dispositiu de rellotge, el qual proporciona una noció precisa i portable del temps real: cada cop

rellotge produeixi una interrupció, incrementarem un comptador, i el lloc apropiat per fer-ho

corresponent rsi, que hem anomenatrellotge (vegeu figura 5.4).

Aquesta rutina posa la variable globalfinal a CERTquan el comptador val 18*5 (5 segons

Trobareu el codi de la rsi al fitxerINTER1.ASM. Es demana que, aprofitant aquest mateix fitx

rellotge procmov ax, @datamov ds, axinc ticscmp tics, 18*5jne rel_sortirmov final, CERT

rel_sortir:mov al, 20hout 20h, aliret

rellotge endp

figura 5.4: Rutina rsi del rellotge

65

Page 67: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

n ja us

escriviu el programa principal (a continuació de l’.startup ) seguint l’esquema de la figura 5.5.

Assembleu i munteu el programa. Executeu-lo directament des del prompt del DOS. Qua

funcioni el programa (ha d’esperar 5 segons i acabar), feu l’exercici 5.3.

Executeu el programa amb la nova rsi corregida. Verifiqueu que funciona bé.

MOV tics, 0;MOV final, FALS;... ; salvar_adreça_vella_vector... ; modificar_adreça_vectorbucle:

CMP final, FALSJE bucle

... ; restaurar_adreça_vella_vector

figura 5.5: Esquema incomplet del programa principal

exercici 5.1

Al codi de la rsi hi hem deixat anar un error, que hauríeu de corregir. Per descobrir-lo,re-escriviu el bucle d’espera del programa principalexactament com el següent:

bucle:MOV AL, finalCMP AL, FALSJE bucle

Executeu el programa. Veureu que ja no funciona. Per què? Escriviu la rsi correcta.

66

Page 68: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

itiu ja

odueixi

l

Activitat 5.B: El teclat

Ara treballarem amb el dispositiu del teclat. Recordeu que la descripció d’aquest dispos

va ser descrita a la lectura prèvia de la sessió 4. Volem fer un programa que acabi quan es pr

la primera interrupció del teclat, de tipusmake. Completeu l’exercici 5.2.

Copieu la rsi en el mateix fitxerINTER1.ASM de l’activitat anterior. Després modifiqueu e

programa principal (recordeu que l’identificador del teclat és el 9).

exercici 5.2

Escriviu aquí el codi de la rsi de teclat

67

Page 69: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

lotge,

de

sol

n

scriu el

àcters

cions.

Activitat 5.C: Rellotge i pantalla

A continuació escriurem un programa un xic més elaborat, que treballarà amb el rel

com en la primera activitat. Utilitzarem el fitxerINTER2.ASM, que conté, ja declarat en el segment

dades, el vector de caràctersstring , de tipus C. Els caràcters estan codificats en ASCII (ocupen 1

byte), i l’últim de tots és un byte 0 (zero).

Feu un programa que escrigui la cadenastring a partir de la posició (2,0) de la pantalla, e

vídeo invers, de forma que passin 0.5 segons (9 tics) des que s’escriu un caràcter fins que s’e

següent. Recordeu com es fa per determinar on està mapejada la pantalla:

call adpantmov es, ax

El programa el plantejarem segons indica la figura 5.6, és a dir, que volem que els car

s’escriguin des de la rsi. El programa principal ja està escrit en el fitxer, i no necessita modifica

Sols heu d’escriure la rsi del rellotge.

Executeu el programa i verifiqueu que funciona bé.

tics++;if (tics==9) {

if (!es_fi_cadena) {tics=0;... // escr_seguent_caracter

}else {

final=CERT;}

}

(rsi rellotge) (prog. principal)

final=FALS;tics=0;while (!final) {};

figura 5.6: Plantejament per resoldre l’activitat 5.C.

68

Page 70: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

lejats

n hagi

cordeu

tejar

mbé en

criguin a

Activitat 5.D: Rellotge, pantalla i teclat

A continuació farem un refinament al programa anterior, en el mateix fitxerINTER2.ASM. Feu

les 2 modificacions a l’hora abans de provar qualsevol de les dues per separat:

Modificació 1) Volem que el programa escrigui a partir de la posició (7,0) els caràcters tec

(en el moment delmake).

Modificació 2) També volem que quan la rsi de rellotge trobi el final de la cadenastring , en

comptes de finalitzar el programa, torni a començar a escriure la cadena, a continuació d’o

acabat d’escriure a pantalla l’anterior cadena. El programa acabarà quan es polsi la tecla ‘F’. Re

com es fa per traduir un codi de rastreig al corresponent caràcter ASCII :

movzx eax, almov bl, tteclat[eax]

De forma similar a l’activitat anterior, l’algorisme que pinta les tecles polsades es pot plan

de dues maneres: o bé escrivint-les des del programa principal, o bé des de la rsi del teclat. I ta

aquest cas volem que se segueixi el segon plantejament, és a dir que les tecles polsades s’es

la pantallades de la rsi de teclat.

Executeu el programa i verifiqueu que funciona correctament.

69

Page 71: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

erò no

gueix

crivint la

n

.3.

Activitat opcional: Accés al segment de dades des de la Rsi

Imagineu què passaria en el programa anterior si restaurem les interrupcions del teclat p

les del rellotge. La idea és la següent: si el programa acaba, i el vector d’interrupcions se

apuntant a la nostra rutina de rellotge, potser aquesta se seguirà executant i doncs, seguirà es

cadenastring a la pantalla (o no?). Sobre el mateix fitxerINTER2.ASM, poseu entre comentaris (u

’;’ a principi de línia) les instruccions que restauren la interrupció del rellotge, i feu l’exercici 5

exercici 5.3

Executeu el programa. Premeu la tecla ’F’ per acabar. Se segueix escrivint lafrase string en pantalla ?

Mentre el rellotge segueix escrivint la cadenastring en pantalla, executeucomandes com CLS o DIR. Executeu també TASM (sense arguments). Quèsucceeix ? Com expliques el diferent comportament en cada cas ?

70

Page 72: Quadern de Laboratoripersonals.ac.upc.edu/miguel/materiales/docencia/EC1/quadern.pdfA la figura 1.2 teniu el codi de la primera pràctica que provarem..model large.386 N EQU -3.stack

grama

ercici

rior !)

uen els

grama

,79),

a ’F’.

Activitat opcional: Una tasca independent per al programa principal

En aquesta activitat farem algunes modificacions al programa anterior per tal que el pro

principal executi una tasca diferent de les del rellotge i el teclat. Abans de seguir, resoleu l’ex

5.4.

A continuació feu les següents modificacions, en el mateix fitxerINTER2.ASM: En primer lloc,

restaureu correctament les interrupcions (heu de treure els ’;’ que heu afegit a l’activitat ante

Mentre s’escriu un caràcter de la cadena cada 0.5 segons a partir de la posició (2,0), i s’escri

caràcters del teclat a la pantalla a partir de la posició (7,0), volem que cada 5 segons el pro

principal canvïi l’atribut de totes les posicions de la pantalla, des de la (0,0) fins a la (24

intercanviant l’atribut normal per invers i viceversa. El programa acabarà quan es polsi la tecl

Executeu el programa i verifiqueu que funciona.

exercici 5.4

Suposem que AL conté l’atribut d’una posició de la pantalla, i aquest val 07h(normal) o bé 70h (invers). Escriviu un codi que canvïi l’atribut de AL denormal a invers i viceversa, amb 1 sola instrucció.

71