Ciao a tutti,
sto continuando ad esercitarmi con il "corso completo di programmazione C" della Deitel e sono arrivato all'esercizio sul simulatore di computer Simpletron.
Penso di essere riuscito a sviluppare il codice così come richiesto dal programma ma ho 2 dubbi:
1-quando l'utente deve digitare "h" per la lista-comandi o "r" per far partire il simulatore, se l'utente digita un carattere diverso il messaggio di avvertimento viene ripetuto 2 volte, e non capisco perché, ho provato sia usando scanf che getchar ma mi da lo stesso problema.
2-Nel libro è scritto che la variabile accumulator dovrebbe essere inizializzata a +0000, instructionCounter a 00, instructionregister a +0000 ecc. ma non riesco a capire come poter fare, io riesco solo a inizializzarle tutte a 0.
3-Ovviamente qualsiasi altro suggerimento per migliorare il codice è ben accetto.
ecco il codice:
#include <stdio.h>
#include <time.h>
void dump( int acc, int iC, int iR, int opCode, int op, int mem[]);
int main (void) {
int memory[1000]={0};
int accumulator=+0000;
int instructionCounter=00;
int instructionRegister=+0000;
int operationCode=00;
int operand=00;
int n=0;
int pause;
int pow,exp;
char list;
system("clear");
printf("\n*** Welcome to Simpletron! ***\n"
"*** Please enter your program one instruction ***\n"
"*** (or data word) at a time. I will type the ***\n"
"*** location number and a question mark (?). ***\n"
"*** You then type the word for that location. ***\n"
"*** Type the sentinel -99999 to stop entering ***\n"
"*** your program. Press h to see Simpletron's ***\n"
"*** version and Simpletron's complete lexicon ***\n"
"*** or simply press r to run Simpletron. ***\n\n");
list=getchar();
while (list!='h' && list!='r'){
printf("Invalid selection. Press h for help"
" or r to run Simpletron.\n");
scanf("%c", &list);
}
if (list=='h'){
printf("\nSimpletron v. 1.2 a machine language simulator\n\n");
printf("read = 10\nwrite = 11\nload = 20\nstore = 21\nadd = 30\n"
"subtract = 31\ndivide = 32\nmodulo = 33\nmultiply = 34\nbranch = 40\n"
"branchneg = 41\nbranchzero = 42\nhalt = 43\n\n");
}
while(memory[n]!=-99999){
printf("%2d ? ", n);
scanf("%d", &memory[n]);
while(memory[n]>4300 || memory[n]<1000){
if(memory[n]!=-99999){
printf("Invalid command. Please insert valid instructions.\n");
printf("%2d ? ", n);
scanf("%d", &memory[n]);
}
else
break;
}
if(memory[n]==-99999)
break;
n++;
}
printf("\n*** Program loading completed ***\n");
pause=time(NULL);
while(time(NULL)-2<pause){
;
}
printf("*** Program execution begins ***\n");
pause=time(NULL);
while(time(NULL)==pause){
;
}
while (instructionRegister!=-99999){
instructionRegister=memory[instructionCounter];
instructionCounter++;
operationCode=instructionRegister/100;
operand=instructionRegister%100;
switch (operationCode){
case 10: /*read*/
printf("? ");
scanf("%d", &memory[operand]);
if(memory[operand]>9999 || memory[operand]<-9999){
printf("*** FATAL ERROR ***\n*** Memory Overflow ***\n"
"Simpletron execution abnormally terminated ***\n");
memory[operand]=9999;
dump(accumulator, instructionCounter, instructionRegister, operationCode, operand, memory);
instructionRegister=-99999;
}
break;
case 11: /*write*/
printf("\n%d\n", memory[operand]);
break;
case 20: /*load*/
accumulator=memory[operand];
break;
case 21: /*store*/
memory[operand]=accumulator;
break;
case 30: /*add*/
accumulator+=memory[operand];
if(accumulator>9999){
printf("*** FATAL ERROR ***\n*** Accumulator Overflow ***\n"
"Simpletron execution abnormally terminated ***\n");
accumulator=9999;
dump(accumulator, instructionCounter, instructionRegister, operationCode, operand, memory);
instructionRegister=-99999;
}
break;
case 31: /*subtract*/
accumulator-=memory[operand];
if(accumulator<-9999){
printf("*** FATAL ERROR ***\n*** Accumulator Overflow ***\n"
"Simpletron execution abnormally terminated ***\n");
accumulator=-9999;
dump(accumulator, instructionCounter, instructionRegister, operationCode, operand, memory);
instructionRegister=-99999;
}
break;
case 32: /*divide*/
if(memory[operand]==0){
printf("*** FATAL ERROR ***\n***Attempt to divide by zero ***\n"
"*** Simpletron execution abnormally terminated ***\n");
dump(accumulator, instructionCounter, instructionRegister, operationCode, operand, memory);
instructionRegister=-99999;
}
else
accumulator/=memory[operand];
break;
case 33: /* modulo */
accumulator%=memory[operand];
break;
case 34: /*multiply*/
accumulator*=memory[operand];
if(accumulator>9999){
printf("*** FATAL ERROR ***\n*** Accumulator Overflow ***\n"
"Simpletron execution abnormally terminated ***\n");
accumulator=9999;
dump(accumulator, instructionCounter, instructionRegister, operationCode, operand, memory);
instructionRegister=-99999;
}
break;
case 35: /* power */
pow=accumulator;
exp=memory[operand];
switch(exp){
case 0:
accumulator=1;
break;
case 1:
break;
default:
for(exp=2;exp<=memory[operand];exp++)
accumulator*=pow;
if(accumulator>9999){
printf("*** FATAL ERROR ***\n*** Accumulator Overflow ***\n"
"Simpletron execution abnormally terminated ***\n");
accumulator=9999;
dump(accumulator, instructionCounter, instructionRegister, operationCode, operand, memory);
instructionRegister=-99999;
}
}
break;
case 40: /*branch*/
instructionCounter=operand;
break;
case 41: /*branchneg*/
if(accumulator<0)
instructionCounter=operand;
break;
case 42: /*branchzero*/
if(accumulator==0)
instructionCounter=operand;
break;
case 43: /*halt*/
printf("\n*** Simpletron execution terminated ***\n");
dump(accumulator, instructionCounter, instructionRegister, operationCode, operand, memory);
instructionRegister=-99999;
break;
}
}
return 0;
}
void dump( int acc, int iC, int iR, int opCode, int op, int mem[]){
int row=0,n=0;
printf("Simpletron Dump:\n");
printf("REGISTERS\n");
printf("accumulator%20d\ninstructionCounter%13d\ninstructionRegister%12d\n"
"operationCode%18d\noperand%24d\n", acc, iC, iR, opCode, op);
printf("MEMORY:\n");
printf(" 0 1 2 3 4 5 6 7 8 9\n");
/*printf("%d ", row);*/
for(n=0;n<1000;n++){
if (n%10==0){
printf("\n");
printf("%3d", row);
row+=10;
}
printf("%6d", mem[n]);
}
printf("\n\n\n");
}
grazie mille
ps per chi volesse compilare il codice su windows, credo bisogni cambiare l'istruzione system("clear") per farlo funzionare, per il resto dovrebbe essere portabile.