• Non ci sono risultati.

4.2 Analisi del codice

4.2.4 Routine di trap

In questa sezione sarà analizzata approfonditamente la gestione delle trap usuali e delle trap di errore, fornendo un esempio dei meccanismi di stampa dei messaggi d'errore.

4.2.4.1 L'istruzione di Trap

Parallelamente a quanto visto per l'interrupt test, si presenta ora quanto avviene durante l'esecuzione di una istruzione INT e come viene utilizzata.

4.2. ANALISI DEL CODICE 75

Struttura dell'istruzione INT L'istruzione INT è stata introdotta per fornire un metodo dedicato ad eettuare le chiamate a sistema più comuni che permet-tono al programma utente di sfruttare in maniera sicura i dispositivi hardware esterni, oltre a fornire un metodo per realizzare la terminazione di un programma utente. L'istruzione di INT è un'istruzione di tipo OPCODE_D8 e il suo codice operativo 0CCh la annovera tra le istruzioni di controllo. Il formato dell'istru-zione è stato appositamente creato in quanto non era presente nelle precedenti versioni di SimCPU e la sua introduzione ha comportato la modica di parte del codice sorgente dell'assemblatore. L'utilizzo dell'istruzione prevede che dopo il suo identicativo INT segua un numero compreso tra 0 e 255 che individua il genere di trap che si vuole chiamare. Questo numero, viene memorizzato nel byte meno signicativo dell'istruzione, all'interno del suo instruction register: ne consegue che la grandezza di quest'istruzione è di una word. Lo scambio dati tra programma utente e programma kernel, vengono eettuati su registri pre-impostati: ad esempio l'esecuzione di una INT 2 (lettura dal buer di tastiera) restituisce il carattere letto nel registro R0. E' cura del programmatore evitare che in R0 siano presenti dati importanti prima dell'esecuzione di una INT 2.

Esecuzione dell'istruzione INT Come già accennato, i passaggi hardware per l'esecuzione dell'istruzione INT sotto riportati ripercorrono a grandi linee quelli proposti nell'interrupt test

case INT : s e t _ s p e c i a l _ r e g i s t e r (LAST_TRAP_INSTRUCTION, r e a d _ i n s t r u c t i o n _ r e g i s t e r ( ) ) ; s e t _ s p e c i a l _ r e g i s t e r (SAVED_STACK_POINTER, r e a d _ r e g i s t e r (STACK_POINTER, NOTRACE) ) ; s e t _ r e g i s t e r (STACK_POINTER,KERNEL_STACK_POINTER) ; s e t _ s p e c i a l _ r e g i s t e r (SAVED_FLAG_REGISTER, r e a d _ s p e c i a l _ r e g i s t e r (FLAG_REGISTER, NOTRACE) ) ; s e t _ s p e c i a l _ r e g i s t e r (SAVED_RETURN_ADDRESS, r e a d _ r e g i s t e r (RETURN_ADDRESS, NOTRACE) ) ; set_flag_kernel_mode ( 1 ) ; d i s a b l e _ i n t e r r u p t s =1; s e t _ r e g i s t e r (RETURN_ADDRESS, read_program_counter ( ) ) ; set_program_counter (TRAP_ROUTINE_PRESET_ADDRESS) ; clear_TLB ( ) ; break ;

I passi percorsi sono esattamente uguali a quelli eseguiti durante a seguito dell'interruzione, con le sole dierenze che da un lato in questo caso non vi è nessun motivo per mettere a zero la linea di interrupt e dall'altro è necessario

introdurre un registro speciale che memorizzi l'informazione necessaria ad identi-care il codice della routine di trap da eseguire. Inoltre la INT comporta sempre il passaggio da programma utente a programma kernel e quindi non serve veri-care che il programma chiamate è di tipo utente per impostare il valore dello stack pointer del kernel. L'utilizzo di INT nel codice kernel non avrebbe infatti alcun senso in quanto sarebbe suciente richiamare l'opportuna funzione.

Il ritorno al codice utente deve avvenire in maniera tale da riprendere l'esecu-zione a partire dall'istrul'esecu-zione successiva a quella che ha generato la chiamata alla trap. Il fatto che l'istruzione di INT sia interamente compresa in una word e che di essa venga normalmente eseguita la fase di instruction fetch con incremento di due unità del program counter, garantisce che il ritorno avvenga in maniera cor-retta in quanto l'indirizzo di memoria del fetch successivo è quello dell'istruzione che succede la INT.

Da notare che anche in questo caso l'indirizzo di salto avviene direttamente in una locazione di memoria predenita e chiamata TRAP_ROUTINE_PRESET_ _ADDRESS il cui valore in questa trattazione è di 0008h. A questa locazione di memoria, mappata sicamente nel primo frame della memoria principale, è presente l'istruzione di branch alla vera e propria routine di gestione delle trap.

Le routine di trap deve soddisfare le stesse caratteristiche di trasparenza e rientranza del codice discusse per quanto concerneva la routine di interruzione.

Le chiamate a INT che lo richiedono, ad esempio quella per la stampa a video (INT 1), operano solo ed esclusivamente su un registro predenito. L'utente, infatti, se vuole stampare a video un carattere, prima di chiamare la rispettiva istruzione di trap, deve posizionare quel carattere nel byte meno signicativo di R0. Lo stesso discorso vale per altri generi di trap, come ad esempio quella che attende la lettura di un carattere dall'indirizzo dati della tastiera: essa infatti restituisce il carattere letto nel byte meno signicativo di R0.

4.2.4.2 Chiamata alla funzione error_trap()

Similmente a quanto avviene per l'istruzione INT, la routine di gestione delle trap viene chiamata anche nel caso si verichino alcuni tra i più comuni errori in fase di esecuzione del programma. La gestione degli errori di sistema, sebbene sia stata di semplice realizzazione una volta ottenuto un sistema di chiamate funzionante e robusto, ha rappresentato un notevole passo avanti per quanto riguarda la si-mulazione del reale funzionamento del sistema operativo. Di fatti, praticamente tutti gli errori che possono attualmente avvenire durante la fase di esecuzione sono gestiti pienamente dal sistema operativo. Nelle versioni precedenti, la stampa del-l'errore era eettuata solamente dal simulatore di SimCPU. Attualmente, qualora l'esecuzione di SimCPU avvenga in modalità Sistema operativo, la generazione degli errori è automaticamente demandata ad esso; d'altro canto, qualora il si-mulatore venga eseguito in modalità Programma utente, l'assenza del sistema operativo per la gestione degli errori necessita il fatto che gli errori stessi vengano ancora gestiti dal codice di SimCPU. Per altre precisazioni riguardanti questa doppia modalità di funzionamento si rimanda alla corrispettiva appendice.

4.2. ANALISI DEL CODICE 77

La funzione di error_trap() ricalca completamente i passi eseguiti dall'istru-zione di INT, con la sola dierenza che il codice contenuto nel Last Trap Instruc-tion non è più quello contenuto dall'instrucInstruc-tion register, ma bensì un codice spe-cico identicativo dell'errore. Inoltre l'errore può avvenire sia in modalità kernel che in modalità utente e quindi anche in questo caso va valutata correttamente l'azione di settaggio dello stack pointer del kernel.

void error_trap ( word error_trap_type ) { s e t _ s p e c i a l _ r e g i s t e r (LAST_TRAP_INSTRUCTION, error_trap_type ) ; i f ( read_flag_kernel_mode (NOTRACE) == 0) { s e t _ s p e c i a l _ r e g i s t e r (SAVED_STACK_POINTER, r e a d _ r e g i s t e r (STACK_POINTER, NOTRACE) ) ; s e t _ r e g i s t e r (STACK_POINTER,KERNEL_STACK_POINTER) ; } s e t _ s p e c i a l _ r e g i s t e r (SAVED_FLAG_REGISTER, r e a d _ s p e c i a l _ r e g i s t e r (FLAG_REGISTER, NOTRACE) ) ; s e t _ s p e c i a l _ r e g i s t e r (SAVED_RETURN_ADDRESS, r e a d _ r e g i s t e r (RETURN_ADDRESS, NOTRACE) ) ; set_flag_kernel_mode ( 1 ) ; d i s a b l e _ i n t e r r u p t s =1; s e t _ r e g i s t e r (RETURN_ADDRESS, read_program_counter ( ) ) ; set_program_counter (TRAP_ROUTINE_PRESET_ADDRESS) ; clear_TLB ( ) ; }

La funzione error_trap() viene chiamata in caso di:

Errore di codice di istruzione: alla ne della funzione executor();

Errore di utilizzo di una istruzione riservata al kernel: ogni qual volta si tenta di eseguire una istruzione riservata al kernel in modalità utente; Errore di indirizzo invalido: nelle istruzioni Input e Output qualora

l'indi-rizzo specicato non sia annoverato tra quelli utilizzabili con quella deter-minata istruzione;

Errore di violazione di accesso di memoria: all'interno delle funzioni me-mory_write() e memory_read() qualora un programma utente tenti di fare riferimento ad una pagina protetta;

Errore di page fault in lettura: quando la pagina che si tenta di leggere non è mappata nella tabella delle pagine relativa al processo;

Errore di page fault in scrittura: quando la pagina nella quale si vuole scrivere non è presente nella tabella delle pagine del processo;

L'esecuzione della error_trap(), e quindi dell'interruzione con codice di errore opportuno, comporta inizialmente la stampa a video del messaggio di errore cor-rispondente ed in seguito la terminazione del programma che l'ha causata. La terminazione di un programma, come sarà fatto notare, viene realizzata median-te un'altra trap, la INT 0, il cui scopo è quello di eseguire tutta quella serie di operazioni (modica di variabili globali del sistema) che accompagnano la ter-minazione di un programma. In seguito viene chiamata la schedulazione del programma successivo.

L'errore di page fault in scrittura, è l'unico errore che attualmente viene gestito correttamente e risolto dalla relativa routine di interruzione, e che dunque non causa l'uscita del programma utente. In questo caso spetta al Sistema Operativo individuare l'istruzione che lo ha generato e allocare all'opportuna pagina il primo frame libero in memoria principale dopo quelli occupati da tutti i programmi utente. L'analisi della gestione di questo genere di page fault non è strettamente compito di questa trattazione in quanto eseguita dall'altro tesista.

Il supporto hardware fornito dal registro speciale LTI per la gestione delle trap e degli errori, rappresenta una semplicazione legittima a questi livelli di simulazione e rende comunque la gestione delle trap molto veloce.

4.2.4.3 Gestione degli errori

Gli errori di funzionamento codicati all'interno di SimCPU e gestiti da er-ror_trap() sono 5 ma ad essi si aggiunge l'ulteriore errore dovuto all'utilizzo di un codice per la INT non implementato (Trap Not Found).

L'elenco completo degli errori e i relativi codici è il seguente: INVALID_INSTRUCTION_OPCODE_ERROR 0xCCFFh INSTRUCTION_USAGE_VIOLATION_ERROR 0xCCFEh UNSUPPORTED_DEVICE_ADDRESS_ERROR 0xCCFDh MEMORY_ACCESS_VIOLATION_ERROR 0xCCFCh PAGE_FAULT_ERROR 0xCCFBh

TRAP_NOT_FOUND_ERROR non codicato

Il codice d'errore è un codice formato da un byte più signicativo che identica l'istruzione di interruzione (L'opcode della INT è infatti CCh) e da un byte meno signicativo che viene decrementato partendo da FFh. Da notare che l'instruction register della istruzione INT 0, ad esempio, è proprio 0xCC00h. Vale a dire che la gestione degli errori viene considerata esattamente come l'esecuzione via hardware di una istruzione di INT. Se nel programma utente chiamassimo l'istruzione INT 0FF, allora otterremmo le stesse conseguenze causate da un errore di istruzione non codicata. Questo fatto è risultato molto importante al ne di vericare il

4.2. ANALISI DEL CODICE 79

corretto funzionamento del sistema di generazione e riconoscimento degli errori in fase di debugging.

Per tutti i generi di errori, escluso il page fault in scrittura, la gestione avviene in maniera identica. Si stampa innanzitutto il messaggio di errore preceduto dalla stringa FATAL ERROR:  e poi si chiama la trap che causa la terminazione del programma che lo ha generato.

Per un'analisi più approfondita sulla gestione del page fault in scrittura, si rimanda alla tesi che lo ha trattato ma a grandi linee può essere così riassunto. L'avvento di un errore di page fault può essere di due tipi, da un lato rappresen-tare un errore di lettura (la pagina che si sta cercando di leggere non è presente in memoria principale) e dall'altro può rappresentare un page fault in scrittura (la pagina che si sta cercando di leggere non è presente in memoria principale). Il secondo tipo di errore di page fault può venire facilmente gestito via software mediante una routine particolare che, dato l'errore di PAGE_FAULT_ERROR (0xCCFBh) va poi a discriminare se si tratti di errore in lettura o in scrittura. Ciò si realizza andando a leggere direttamente l'istruzione che lo ha causato: qua-lora si trattasse di una Store alqua-lora l'errore è in scrittura, quaqua-lora si trattasse di una Load allora l'errore è in lettura. Il fetching dell'area di memoria nel quale è presente l'istruzione di load o di store, tuttavia, non è semplice in quanto l'architettura, essendo a 16bit non può accedere a tutta la memoria principale in maniera diretta. Questa limitazione viene evitata andando a copiare la pagina che ha causato il page fault (determinabile mediante l'indirizzo base della tabella delle pagine del programma utente e il valore del program counter prima dell'av-venimento dell'errore - contenuto in RA) e mappandola, modicando la tabella delle pagine del kernel, in un frame particolare del sistema operativo stesso e leggendovi da essa.

Le metodologie di stampa a video degli errori verranno analizzate in seguito. 4.2.4.4 Routine di Trap

La routine di trap consta di una parte generale di salvataggio dei registri, ne-cessaria a garantire le caratteristiche che sono già state analizzate, una sezione nella quale viene decodicato il codice della trap, e un'ultima parte nella quale vengono chiamate ed eseguite la varie routine.

Il codice utilizzato per la stampa dei messaggi è ridondante e ne verrà citata solamente una parte esemplicativa.

TRADD: PUSH R12 LSR SRA R12 PUSH R12 LSR SFR R12 PUSH R12 LSR SSP R12 PUSH R12 EINT ; s a l v a t a g g i o n e l l o s t a c k d e i r e g i s t r i ; s p e c i a l i SRA, SFR e SSP e s a l v a t a g g i o ; d e l r e g i s t r o di i n t e r s c a m b i o R12 .

; a b i l i t a z i o n e i n t e r r u z i o n i PUSH R11 PUSH R10 PUSH R9 ; s a l v a t a g g i o d i r e g i s t r i di i n t e r s c a m b i o LSR LTI R10 LDWI R11 0FF00 AND R11 R10 LDWI R9 0CC00 SUB R10 R9 JMPZ TRADD_C BR N_INT_T ; v a l u t a z i o n e d e l l 'OPCODE d e l l ' i s t r u z i o n e ; che ha causato l a trap . Qualora t a l e v a l o r e ; non s i a 0CCh, s a l t o a l l a l o c a z i o n e

; N_INT_T ( Not INT Trap ) TRADD_C: LSR LTI R10

LDWI R11 00FF AND R11 R10

; In R10 l ' i n d i c e d e l l a trap chiamata , ; è contenuto n e l byte meno s i g n i f i c a t i v o ; d e l r e g i s t r o LTI che c o n t i e n e

; l ' i n s t r u c t i o n r e g i s t e r d e l l ' i s t r u z i o n e ; che ha causato l a trap

LDWI R11 0 SUB R10 R11 JMPNZ N_00_C BR EX_T ; v a l u t a z i o n e d e l l ' i n d i c e 0 , e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e INT 0 N_00_C: LDWI R11 1 SUB R10 R11 JMPNZ N_01_C

BR OB_T ;OUTB TRAP ; v a l u t a z i o n e d e l l ' i n d i c e 0 , e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e INT 0 N_01_C: LDWI R11 2

SUB R10 R11 JMPNZ N_02_C

BR IB_T ; INB TRAP − INT 2 ; v a l u t a z i o n e d e l l ' i n d i c e 1 , e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e INT 1 N_02_C: LDWI R11 0FF

SUB R10 R11 JMPNZ N_FF_C

BR ER_T_IIS ;ERROR TRAP INVLALID INSTRUCTION CODE ; v a l u t a z i o n e d e l l ' i n d i c e 2 , e v e n t u a l e

; s a l t o a l l a r o u t i n e che g e s t i s c e INT 2 N_FF_C: LDWI R11 0FE

SUB R10 R11 JMPNZ N_FE_C

BR ER_T_IUV ;ERROR TRAP INSTRUCTION UNSAGE VIOLATION ; v a l u t a z i o n e d e l l ' i n d i c e FF, e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e i l ; r e l a t i v o e r r o r e N_FE_C: LDWI R11 0FD SUB R10 R11 JMPNZ N_FD_C

BR ER_T_UDA ;ERROR TRAP UNSUPPORTED DEVICE ADDRESS ; v a l u t a z i o n e d e l l ' i n d i c e FE, e v e n t u a l e

4.2. ANALISI DEL CODICE 81 ; s a l t o a l l a r o u t i n e che g e s t i s c e i l ; r e l a t i v o e r r o r e N_FD_C: LDWI R11 0FC SUB R10 R11 JMPNZ N_FC_C

BR ER_T_MAV ;ERROR TRAP MEMORY ACCESS VIOLATION ; v a l u t a z i o n e d e l l ' i n d i c e FD, e v e n t u a l e

; s a l t o a l l a r o u t i n e che g e s t i s c e i l ; r e l a t i v o e r r o r e

N_FC_C: LDWI R11 0FB SUB R10 R11

JMPNZ ER_T_TNF ;ERROR TRAP NOT FOUND

BR ER_T_RPF ;ERROR TRAP READINDG PAGE FAULT ; v a l u t a z i o n e d e l l ' i n d i c e FC, e v e n t u a l e

; s a l t o a l l a r o u t i n e che g e s t i s c e i l ; r e l a t i v o e r r o r e ed e r r o r e di

; Trap Not Found qualora l ' i n d i c e e s t r a p o l a t o ; non c o r r i s p o n d a nemmeno a quest ' ultimo c o d i c e TR_CON: POP R9

POP R10 POP R11

; u s c i t a normale da una r o u t i n e di trap ; r i p r i s t i n o d e i r e g i s t r i d i i n t e r s c a m b i o DINT POP R12 SSR SSP R12 POP R12 SSR SFR R12 POP R12 SSR SRA R12 POP R12 IRET ; r i p r i s t i n o d e i r e g i s t r i s p e c i a l i , ; d e l r e g i s t r o d i i n t e r s c a m b i o e r i t o r n o ; a l programma chiamante

EX_T: LDWA R13 READY DEC R13 JMPZ END_EX_T STWA R13 READY LDWA R0 EX_PID LDWI R1 LIST DEC R0 ADD R0 R1 ADD R0 R1 INC R1 LDWI R2 0 STBR R2 R1 BR SCHED END_EX_T: HLT

; Codice per INT 0 , se l ' e s e c u z i o n e d i questa ; trap porta a l l ' azzeramento d e l l a v a r i a b i l e ; READY, l a s i m u l a z i o n e s i interrompe

OB_T: OUTB R0 0002 BR TR_CON

; INT 1 , e s e c u z i o n e d e l l a stampa a video ; s u l c a n a l e d a t i d e l monitor d e l byte ; meno s i g n i f i c a t i v o contenuto i n R0 IB_T : PUSH R1 LDWI R1 1 IB_T_L: INB R0 0003 SUB R1 R0 JMPNZ IB_T_L

INB R0 0004 LDWI R1 0 OUTB R1 0003 POP R1 BR TR_CON ; INT 2 , l e t t u r a c i c l i c a d e l c a n a l e di ; c o n t r o l l o d e l l a t a s t i e r a ed a t t e s a d e l ; riempimento d e l b u f f e r d i i n g r e s s o con ; almeno un c a r a t t e r e . S u c c e s s i v a l e t t u r a ; d e l c a r a t t e r e

ER_T_TNF: CALL P_FE CALL P_TRAP CALL P_SPACE CALL P_NOT CALL P_SPACE CALL P_FOUND CALL P_NLINE BR EX_T

; Stampa a video d i un messaggio ; e s e g u i t a mediante composizione ; d e l l o s t e s s o con chiamate a ; f u n z i o n i a d i b i t e a l l o scopo . . .

La fase iniziale e la fase nale della routine di trap sono riportate qui sotto. Esse ricalcano in maniera quasi perfetta quelle caratteristiche della routine di interrupt eccezion fatta per la dierente scelta del registro di interscambio per la realizzazione dei push e dei pop dei registri speciali, nonché il push sullo stack (e il relativo pop), di tre ulteriori registri (R11, R10, R9) che verranno utilizzati nel corpo della trap per eseguire le manipolazioni dei dati necessarie.

TRADD: PUSH R12 LSR SRA R12 PUSH R12 LSR SFR R12 PUSH R12 LSR SSP R12 PUSH R12 EINT ; s a l v a t a g g i o n e l l o s t a c k d e i r e g i s t r i ; s p e c i a l i SRA, SFR e SSP e s a l v a t a g g i o ; d e l r e g i s t r o d i i n t e r s c a m b i o R12 . ; a b i l i t a z i o n e i n t e r r u z i o n i PUSH R11 PUSH R10 PUSH R9 ; s a l v a t a g g i o d i r e g i s t r i d i i n t e r s c a m b i o . . . TR_CON: POP R9 POP R10 POP R11

; u s c i t a normale da una r o u t i n e di trap ; r i p r i s t i n o d e i r e g i s t r i di i n t e r s c a m b i o

4.2. ANALISI DEL CODICE 83 DINT POP R12 SSR SSP R12 POP R12 SSR SFR R12 POP R12 SSR SRA R12 POP R12 IRET ; r i p r i s t i n o d e i r e g i s t r i s p e c i a l i , ; d e l r e g i s t r o di i n t e r s c a m b i o e r i t o r n o ; a l programma chiamante

All'inizializzazione segue la parte di decodica. Come già accennato, il page fault in scrittura viene gestito separatamente e di esso se ne valuteranno solamente le condizioni per la relativa routine chiamata.

. . . LSR LTI R10 LDWI R11 0FF00 AND R11 R10 LDWI R9 0CC00 SUB R10 R9 JMPZ TRADD_C BR N_INT_T ; v a l u t a z i o n e d e l l 'OPCODE d e l l ' i s t r u z i o n e ; che ha causato l a trap . Qualora t a l e v a l o r e ; non s i a 0CCh, s a l t o a l l a l o c a z i o n e

; N_INT_T ( Not INT Trap ) TRADD_C: LSR LTI R10

LDWI R11 00FF AND R11 R10

; In R10 l ' i n d i c e d e l l a trap chiamata , ; è contenuto n e l byte meno s i g n i f i c a t i v o ; d e l r e g i s t r o LTI che c o n t i e n e

; l ' i n s t r u c t i o n r e g i s t e r d e l l ' i s t r u z i o n e ; che ha causato l a trap

. . .

In questa parte di codice si verica inizialmente che l'OPCODE della funzione chiamante sia quello caratteristico della INT e qualora non risulti cosi, viene stampato un messaggio di errore opportuno e terminato il relativo programma.

Ad ogni modo, una volta individuato il fatto che la causa scatenante della trap è stata una istruzione di INT o un errore, è necessario estrapolare dall'instruction register l'identicativo dell'interruzione chiamante. Ciò si realizza applicando al registro LTI (che nel frattempo è stato copiato in R10), la maschera 00FF. In R10 vi è l'indirizzo della trap che è stata chiamata.

A questo punto segue la fase nella quale eseguire i vari confronti ed operare il salto alla routine corretta. Considerato il numero di righe di codice utilizzato, i

salti condizionati alle routine di codice non possono venire eettuati mediante le normali istruzioni di JMP in quanto esse operano solo su intervalli di 256 byte al massimo. E' necessario dunque eseguire dei salti mediante Branch e ciò complica questa fase anche se di poco.

. . . LDWI R11 0 SUB R10 R11 JMPNZ N_00_C BR EX_T ; v a l u t a z i o n e d e l l ' i n d i c e 0 , e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e INT 0 N_00_C: LDWI R11 1 SUB R10 R11 JMPNZ N_01_C

BR OB_T ;OUTB TRAP ; v a l u t a z i o n e d e l l ' i n d i c e 0 , e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e INT 0 N_01_C: LDWI R11 2

SUB R10 R11 JMPNZ N_02_C

BR IB_T ; INB TRAP − INT 2 ; v a l u t a z i o n e d e l l ' i n d i c e 1 , e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e INT 1 N_02_C: LDWI R11 0FF

SUB R10 R11 JMPNZ N_FF_C

BR ER_T_IIS ;ERROR TRAP INVLALID INSTRUCTION CODE ; v a l u t a z i o n e d e l l ' i n d i c e 2 , e v e n t u a l e

; s a l t o a l l a r o u t i n e che g e s t i s c e INT 2 N_FF_C: LDWI R11 0FE

SUB R10 R11 JMPNZ N_FE_C

BR ER_T_IUV ;ERROR TRAP INSTRUCTION UNSAGE VIOLATION ; v a l u t a z i o n e d e l l ' i n d i c e FF, e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e i l ; r e l a t i v o e r r o r e N_FE_C: LDWI R11 0FD SUB R10 R11 JMPNZ N_FD_C

BR ER_T_UDA ;ERROR TRAP UNSUPPORTED DEVICE ADDRESS ; v a l u t a z i o n e d e l l ' i n d i c e FE, e v e n t u a l e ; s a l t o a l l a r o u t i n e che g e s t i s c e i l ; r e l a t i v o e r r o r e N_FD_C: LDWI R11 0FC SUB R10 R11 JMPNZ N_FC_C

BR ER_T_MAV ;ERROR TRAP MEMORY ACCESS VIOLATION ; v a l u t a z i o n e d e l l ' i n d i c e FD, e v e n t u a l e

; s a l t o a l l a r o u t i n e che g e s t i s c e i l ; r e l a t i v o e r r o r e

N_FC_C: LDWI R11 0FB SUB R10 R11

JMPNZ ER_T_TNF ;ERROR TRAP NOT FOUND

BR ER_T_RPF ;ERROR TRAP READINDG PAGE FAULT ; v a l u t a z i o n e d e l l ' i n d i c e FC, e v e n t u a l e

4.2. ANALISI DEL CODICE 85

; r e l a t i v o e r r o r e ed e r r o r e di

; Trap Not Found qualora l ' i n d i c e e s t r a p o l a t o ; non c o r r i s p o n d a nemmeno a quest ' ultimo c o d i c e . . .

Se il confronto tra il dato contenuto in R10 (che rappresenta il codice della trap chiamata) e il dato contenuto in R11 (ovvero il codice di confronto) restituisce zero, allora l'istruzione di Branch viene eseguita, altrimenti si passa al confronto con il codice successivo. Nel caso in cui nessun confronto vada a buon ne si verica l'errore di TRAP_NOT_FOUND_ERROR.

INT 0 Qualora quella chiamata sia la routine corrispondente alla INT 0, il codice eseguito è il seguente.

EX_T: LDWA R13 READY DEC R13 JMPZ END_EX_T STWA R13 READY LDWA R0 EX_PID LDWI R1 LIST DEC R0 ADD R0 R1 ADD R0 R1 INC R1 LDWI R2 0 STBR R2 R1 BR SCHED END_EX_T: HLT

; Codice per INT 0 , se l ' e s e c u z i o n e d i questa ; trap porta a l l ' azzeramento d e l l a v a r i a b i l e ; READY, l a s i m u l a z i o n e s i interrompe

Per capire a fondo il codice della Trap di uscita (Exit_Trap) dai programmi utente, sarebbe necessario conoscere molto bene il listato dello scheduler. Tutta-via, si richiamano ora i concetti fondamentali necessari almeno alla comprensione della funzione sopra riportata:

READY: variabile globale che identica il numero di programmi utente ancora in esecuzione nel sistema. Ogni volta che viene chiamata la fun-zione EXIT_TRAP questa variabile viene decrementata. Qualora a causa del decremento tale variabile si porti a zero ciò implica che non ci sono più programmi utente in grado di girare. Considerato che non vi è ancora la possibilità di caricare programmi in memoria durante il funzionamento del sistema operativo, il sistema operativo stesso non ha alcuna ragione di continuare a funzionare: viene eseguita l'istruzione di HALT (HLT) che sostanzialmente spegne il sistema operativo e la macchina. Qualora il ri-sultato del decremento non sia nullo, ovvero ci siano ancora programmi in grado di essere schedulati, la variabile READY viene aggiornata.

EX_PID: rappresenta il Process IDenticator del programma in esecuzione, ovvero del programma che è stato interrotto, nonché del programma che dovrà venire schedulato. Cambiare opportunamente questa variabile ed in seguito chiamare lo scheduler equivale ad eseguire il context switching in favore del programma identicato dal nuovo valore di EX_PID.

LIST: è un indirizzo in memoria che individua l'inizio di un array che con-tiene la lista degli stati dei programmi. La terminazione di un programma necessita l'opportuno aggiornamento di questa lista.

A seguito dell'aggiornamento della lista viene chiamato lo scheduler per eettuare l'avvicendamento nella CPU del successivo programma.

INT 1 Questa trap realizza la stampa a video di un carattere. Il carattere in questione, deve venire posto dall'utente nel byte meno signicativo del registro R0

OB_T: OUTB R0 0002 BR TR_CON

; INT 1 , e s e c u z i o n e d e l l a stampa a video ; s u l c a n a l e d a t i d e l monitor d e l byte ; meno s i g n i f i c a t i v o contenuto i n R0

In questo caso la comunicazione tra architettura e thread del monitor viene simulata direttamente all'interno dell'istruzione OUT, come si è già avuto modo di vedere.

INT 2 Esegue l'operazione di lettura di un carattere da tastiera con blocco del funzionamento del programma. Il context switching, per il momento, non è stato abilitato durante l'esecuzione di un blocco di memoria scritto in codice

Documenti correlati