Adresse Code
machine Code assembleur
0100
A20220 MOV [2002],AL
Dans la mémoire de données on a les octets suivants :
Adresse
Données
Ascii
2000 00 00 00 00 00 00 00 00 ......
1. Mettre en évidence l'évolution des valeurs sur les bus d'adresses
et de données ainsi que l'évolution des signaux de lecture et d'écriture, lors
de l'exécution de cette instruction.
A0-A15
D0-D7
RDbarre
WRbarre
2. Chaque cycle de bus (lecture ou écriture) dure 2 périodes Th de l'horloge du microprocesseur. Sachant qu'il fonctionne à 4 MHz, calculer le temps d'exécution de cette instruction.
3. Représenter la mémoire de données après exécution de cette instruction.
Adresse
Données
Ascii
2000
4. En admettant que ce processeur continue à fonctionner à 40 MHz, des mémoires statiques de 80 ns de temps d'accès seraient-elles capables de tenir le rythme imposé par ce processeur ? Justifier la réponse.
Situation initiale | AX=4282 BX=2000 CX=0000 DX=0000 |
SI=0004 DI=0002 BP=FF50 SP=FF40 |
Adresse
Données
Ascii 2000 00 01 02 03 04 05 06 07 ........ ... FF40 00 00 00 00 00 00 00 00 ........ FF48 00 00 00 00 00 00 00 00 ........ FF50 00 00 00 00 00 00 00 00 ........ |
MOV BX,CX | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
MOV [BX],AH | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
MOV [2000],CX | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
MOV CX,2000 | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
MOV BP,SP | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
MOV [BP-2],BP | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
MOV [BX+SI+2],0 | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
MOV [BP+DI],1 | AX= BX= CX= DX= |
SI= DI= BP= SP= |
Adresse
Données
Ascii 2000 ........ ... FF40 ........ FF48 ........ FF50 ........ |
Dans ce code, les pointeurs sont supposés NEAR (intra-segment). Imaginer le code assembleur généré par un compilateur C pour les deux instructions en caractères gras :
/* type */
struct Entry {
char *name;
char *phoneNumber;
};
/* variables globales */
struct Entry
directory[100];
struct Entry newEntry;
/* extrait d'une fonction */
directory[i].name = newEntry.name;
directory[i].phoneNumber = newEntry.phoneNumber;
cmp v1,FALSE
je
etiq0
mov bx,offset v3
mov v2,0
etiq1:
cmp v2,CONST1
jge
etiq2
mov si,v2
add si,si
mov [bx+si],NULL
inc v2
jmp etiq1
etiq2:
mov v1,FALSE
etiq0:
int checkMin( int tab[100], int min )
{
int i;
...
return min;
}
1. Dessiner le contexte de pile complètement annoté, manipulé par la fonction checkMin. Il n'est pas demandé de traduction en assembleur de l'implantation de la fonction checkMin.
Dans le même programme, on considère la fonction main qui appelle la fonction checkMin.
int main()
{
int
tmp[100];
int minValue;
getData( tmp );
minValue = tmp[0];
minValue = checkMin( tmp, minValue );
printf( "Le minimum est %d\n", minValue );
return 0;
}
2. Imaginer le code généré par un compilateur C pour implanter le comportement de l'instruction minValue = checkMin( tmp, minValue );
#define MAX_PROC 10
createProcess( 0, proc0, SS_PROC0, 32000 );
createProcess(
1, proc1, SS_PROC1, 32000 );
...
createProcess( 9,
proc9, SS_PROC9, 32000 );
start( 0 );
On voit que, dans un premier temps, on initialise le contexte des processus proc0 à proc9 puis une procédure start démarre l'ordonnancement par le processus de numéro 0.
On spécifie createProcess de la façon suivante :
Le paramètre
numProc est le numéro de processus.
Le paramètre
processBeginAdress est un pointeur far contenant l'adresse de la
première instruction du processus.
Le paramètre stackSeg contient
la partie segment de l'adresse de début du segment de pile du processus.
Le
paramètre stackSize contient la taille du segment de pile.
typedef void Process_type();
void createProcess( int numProc, Process_type far *processBeginAddress,
int stackSeg, int stackSize )
{
//
à compléter
}
Les processus proc0 à proc9 sont disciplinés. Ils sont donc supposés contenir :
pushf
callf
_schedule
afin de ne pas conserver le processeur indéfiniment.
Question : proposer une implantation pour createProcess.
...
pushf
callf
_schedule
...
void schedule() asm {
// save calling process context
(flags, CS, IP already stacked)
push
ax
push bx
push
cx
push dx
push
si
push di
push
bp
push es
push
ds
// load scheduler ds value
mov
ax,SEG tab_Proc
mov ds,ax
// tab_Proc[currentProc] =
calling process SS:SP value
mov
bx,OFFSET tab_Proc
mov si,currentProc
mov
di,si
add di,di
add
di,di
mov [bx+di],sp
mov
ax,ss
mov [bx+di+2],ax
// currentProc =
(currentProc+1) % MAX_PROC
inc
si
cmp si,MAX_PROC
jne
fsi0
xor si,si
fis0:
mov currentProc,si
// SS:SP =
tab_Proc[currentProc]
add si,si
add
si,si
mov sp,[bx+si]
mov
ax,[bx+si+2]
mov ss,ax
// restore new elected process
context
pop ds
pop
es
pop bp
pop
di
pop si
pop
dx
pop cx
pop
bx
pop ax
iret
}