Simulatore simpletron

di il
4 risposte

Simulatore simpletron

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.

4 Risposte

  • Re: Simulatore simpletron

    1) getchar / scanf ==> getchar / getchar || scanf / scanf
    2) zero è uguale a zero. L' autore evidentemente ha fumato
  • Re: Simulatore simpletron

    Grazie ixamit per la risposta.
    avevo provato sia utilizzando 2 scanf, sia 2 getchar. Nel codice postato li ho messi entrambi giusto per indicare esattamente che istruzioni ho utilizzato. Ma in tutti e tre i casi ripete 2 volte l'istruzione printf e non capisco perchè.
  • Re: Simulatore simpletron

    Non sono un'amante del codice ripetuto... se proprio devo farlo preferirei due chiamate identiche.
    Il buff di tastiera rimane sporco o anteponi uno spazio nella scanf tipo:
    
      scanf(" %c", &list);
            ^^
    
    o fai qualcosa tipo:
    
      while(getchar()!='\n');
    
    Riassumendo, qualcosa tipo:
    
       for (;(list=getchar())!='r' && list!='h';)
       {
         while(getchar()!='\n');
         printf("Invalid selection. Press h for help\n");
       }
    
    ~Max
  • Re: Simulatore simpletron

    Grazie mille, interessante il discorso sul buff di tastiera sporco, avevo ipotizzato qualcosa di simile ma non ne capivo esattamente il funzionamento.
    ho provando anteponendo lo spazio e (ovviamente) funziona, non ci sarei arrivato da solo, e non avevo pensato nemmeno ad utilizzare il getchar()!='\n', che in effetti mi sembra la soluzione migliore. grazie ancora!
Devi accedere o registrarti per scrivere nel forum
4 risposte