シンプルなSimpleTron(C言語実装、プログラム内部実装体験)


簡単な紹介
Simpletronは簡単な機械で、CPU、コントローラ、メモリなどの体現を持っていて、コンピュータの基礎と原理を簡単に説明しました.Simpletronは、それが理解できる唯一の言語、すなわちSimpletronマシン言語(SMLと略称)で作成されたプログラムにのみ適用される.
Simpletronは、計算および処理のためのSimpletronの様々な情報を格納するアキュムレータ(AC、「特殊レジスタ」)を含む.
Simpletronのすべての情報(命令とデータを含む)は「字」に従って処理されます.ワードは、符号付き4ビット10進数(例えば8086は16ビットマシンであり、16ビット(2バイト、16バイナリビット、4 16 16進数)のデータ命令しか処理できない)であり、例えば+3364、-1293、+0007、-001など、SML命令の記号は常に正の符号であると仮定するが、データの記号は正の符号で負の符号であってもよい.
Simpletronは100文字のメモリを持ち、これらの文字はそれらの位置番号00,01,...,99によって参照される.メモリ内の各位置は、命令、またはプログラムが使用するデータ値、または未使用のメモリであってもよい.
SMLプログラムを実行する前に、プログラムをメモリに配置する必要があります.各SMLプログラムの最初の命令(または文)は常に位置00に置かれ、
その後の命令は、転送命令に遭遇しない限り、順次保存され、00という位置から実行され、実行も順次実行される.
各SML命令について、その最初の2桁の数字は操作コードであり、実行する操作を指定する.後ろの2桁の数字はオペランド(アドレスコードとも呼ばれる)であり、操作するメモリ位置(データのアドレスであってもよいし、オペランドが転送コマンドの場合、オペランドはコマンドのアドレスであってもよい)である.すでに現代機械の指令によく似ているが、現代機械にはより多くのアドレス方式がある.二具体分析
オペレーションコードが表すオペレーション
入出力操作
#define READ		10 //             read
#define WRITE		11 //           write

読み込みと保存
#define LOAD		20//          load
#define STORE		21//              store

さんじゅつえんざん
#define ADD		30//               addition
#define SUBTRACT	31//               subtract
#define DIVIDE		32//              division
#define MULTIPLY	33//               multiplication

せいぎょてんい
#define BRANCH		40//          
#define BRANCHNEG	41//        ,         
#define BRANCHZERO 	42//        ,         
#define HALT		43//     ,    
    (  )
00 +1008    A  08,       ,     
01 +1009    B  09
02 +2008  A      
03 +3009       (A)  B
04 +2110    C   10(      ,             )
05 +1110  C    (    )
06 +4300     
07 +0000     (     )
08 +0000 A   
09 +0000 B   
10 +0000 C   
メモリとアキュムレータの定義と初期化は、次のとおりです.
//SimpleTron    
#define MEMORY_COUNTER 100
int memory[MEMORY_COUNTER];
//アキュムレータの定義と初期化
int accumulator = +0000;

メモリがあれば、命令を格納する場所があることは明らかですが、命令をどのように取得し、命令を分析処理して、命令の操作とデータ値を明確にするには、命令レジスタ(IR)を1つ必要とします(メモリから命令を取った後、命令レジスタを命令デコーダの操作コードの分析(ID)のために命令レジスタに置きます.
//命令レジスタの定義と初期化--メモリから命令を1つずつロードして保存する
int instructionRegister = +0000;
命令を必要とする統計
//プログラムカウンタ:命令の統計が必要です(プログラムカウンタの本当の役割は、プログラムの実行順序を制御するための次の命令を指します)
int structionCounter = 00;
次は操作コードと操作数を分ける(CPU制御では、操作コードをデコーダに送り、命令解析を行い、操作数をアドレスレジスタ(AR、格納アドレス、アドレスバスを介してメモリに接続する)、またはプログラムカウンタ(転送命令に対する))
//操作コードの定義と初期化
int operationCode = 00;  
//オペランド定義と初期化
int operand = 00; 

以上はメインレジスタの定義と初期化プログラムの前に必要なヒントで、出力します.
* * * Welcome to Simpletron * * *
* * * Please enter your program one istruction * * *
* * * (or data word) at a time .I will type the * * *
* * * Location number and a question mark(?). * * *
* * * You then tupe the word for that location. * * *
* * * Type the sentinel -99999 to stop entering * * *
* * * You program. * * *

最後から2番目の文は-999999で入力を終了し、メモリなどを印刷する場合です.これは、命令やデータの格納位置をより明確にするために、メモリごとの状況を印刷し、アキュムレータや命令数などを明確にするためです(エラー時のデバッグが便利です).この部分はプログラム設計の最後の部分に置くことができ、説明に値する前の-4300はプログラム命令を停止し、メモリの位置は-9999より前であるべきであり、-9999は必要なプログラム制御であり、プログラム命令ではないので、命令カウント時に無視しなければならない.
次は関数定義です.
コマンドの入力
void enterInstruction(void);//     

-99999で変数データを提示する入力に遭遇した場合
* * * Program loading completed * * *
* * * Program execution begins * * *

ロード、コマンドを1つずつ取得
void loadRegister(void)
{
instructionRegister = memory[instructionCounter];    //load instruction to register
}

めいれいかいせつ
void translateInstruction(void);//    

オペレーションコードの取得方法
operationCode = instructionRegister / 100;

オペランドの取得方法
operand = instructionRegister % 100;

操作コードと操作数判断,if(operand<0 OR operand>99)に対して異常処理関数を呼び出す.
じっこうめいれい
void carryInstruction(void);  //     

これは大きなswitch文です
switch(operationCode)
case READ:    
scanf("%d",&memory[operand]);
if(memory[operand]9999)
{
    exception(EXCEPTION_INPUT_DATA);	
    break;
} 
instructionCounter++;
break;

case WRITE:    
printf("%d
",memory[operand]); instructionCounter++; break; // …
操作が成功するたびに、命令カウンタに1を加算することに注意する
.
コンピュータコンテンツ印刷
void computerDump(void);//        
適切なフォーマット制御を行う
例外処理
void exception(ERROR error);//    ,              ,           

コード#コード#
//simpletron.c

//

#include 

#define MEMORY_COUNTER 100    //counter of memory


#define READ       10
#define WRITE      11

#define LOAD       20
#define STORE      21

#define ADD        30
#define SUBTRACT   31
#define DEVIDE     32
#define MULTIPLY   33

#define BRANCH     40
#define BRANCHNEG  41
#define BRANCHZERO 42
#define HALT       43
/

int accumulator         = +0000;     //define accumulator and initialize to zero
int instructionCounter  = 00;    //define instruction counter and initialize to zero
int instructionRegister = +0000;    //define register to load instruction and initialize
int operationCode       = 00;    //define operationCode and initialize to zero
int operand             = 00;    //define operand and initialize to zero

int memory[MEMORY_COUNTER];    //memory

//instrution of error
typedef enum{EXCEPTION_INPUT_DATA, 
	EXCEPTION_INSRUCTION, 
	EXCEPTION_ERROR_DIVIDED, 
	EXCEPTION_OUT_ACCUMULATOR, 
	EXCEPTION_ERROR_OPERAND
}ERROR;

//before

void enterInstruction(void);
void loadRegister(void);
void translateInstruction(void);
void carryInstruction(void);
void computerDump(void);
void exception(ERROR error);

//function of  instruction

void enterInstruction(void)
{
	printf("* * * Welcome to Simpletron * * *
"); printf("* * * Please enter your program one istruction * * *
"); printf("* * * (or data word) at a time .I will type the * * *
"); printf("* * * Location number and a question mark(?). * * *
"); printf("* * * You then tupe the word for that location. * * *
"); printf("* * * Type the sentinel -99999 to stop entering * * *
"); printf("* * * You program. * * *
"); int temporary_i = 0; while(1) { printf("%02d?",temporary_i); //output information to get instruction scanf("%d",&memory[temporary_i]); //get instruction if(memory[temporary_i] == -99999) //end of -99999 { printf("* * * Program loading completed * * *
"); printf("* * * Program execution begins * * *
"); break; } temporary_i++; //add one } } //function of load instruction to register void loadRegister(void) { instructionRegister = memory[instructionCounter]; //load instruction to register } //function of translate instruction to oprationcode and oprand void translateInstruction(void) { operationCode = instructionRegister / 100; //control accumulator get instruction code operand = instructionRegister % 100; //control accumulator get operand if(operand < 0||operand >99) exception(EXCEPTION_ERROR_OPERAND); } //function of carry out struction void carryInstruction(void) { switch(operationCode) { case READ: //read data from std intput scanf("%d",&memory[operand]); if(memory[operand]9999) { exception(EXCEPTION_INPUT_DATA); break; } instructionCounter++; break; case WRITE: //write data to std ouput printf("%d
",memory[operand]); instructionCounter++; break; case LOAD: //add data to accumulator from memory accumulator = memory[operand]; instructionCounter++; break; case STORE: //transfer data of accumulator to memory memory[operand] = accumulator; instructionCounter++; break; case ADD: //data of accumulator add to memory data accumulator += memory[operand]; if(memory[operand]9999) { exception(EXCEPTION_OUT_ACCUMULATOR); break; } instructionCounter++; break; case SUBTRACT: //data of accumulator subtract memory data accumulator -= memory[operand]; if(memory[operand]9999) { exception(EXCEPTION_OUT_ACCUMULATOR); break; } instructionCounter++; break; case MULTIPLY: //data of accumulator multiply memory data accumulator *= memory[operand]; if(memory[operand]9999) { exception(EXCEPTION_OUT_ACCUMULATOR); break; } instructionCounter++; break; case DEVIDE: //data of accumulator divide memory data accumulator /= memory[operand]; if(memory[operand] == 0) { exception(EXCEPTION_ERROR_DIVIDED); break; } instructionCounter++; break; case BRANCH: instructionCounter = operand; break; case BRANCHNEG: //if accumulator less than zero, //if accumulator equal to zero, transfer memory if(accumulator < 0) instructionCounter = operand; else instructionCounter++; break; case BRANCHZERO: //if accumulator equal to zero, transfer memory if(accumulator == 0) instructionCounter = operand; else instructionCounter++; break; case HALT: //if operation code equal to 43, break program printf("* * * Simpletron execution terminated * * *
"); break; default: //carry out other instruction code exception(EXCEPTION_INSRUCTION); break; } } //function of computer dump void computerDump(void) { // int temporary_i, temporary_j, temporary_k, temporary_l = 00, temporary_m = 00, temporary_n = 0; printf("
"); /// print the data of simpletron printf("accumulator %d
",accumulator); printf("instructionCounter %d
",instructionCounter); printf("instructionRegister %d
",instructionRegister); printf("operationCode %d
",operand); printf("operand %d
",operand); printf("memory:
"); //print memory data printf("%2c",' '); //control for(temporary_i = 0; temporary_i < MEMORY_COUNTER / 10; temporary_i++) { printf("%8d",temporary_l); temporary_l++; } printf("

"); for(temporary_j = 0; temporary_j < MEMORY_COUNTER / 10; temporary_j++) { printf("%2d",temporary_m); temporary_m += 10; for(temporary_k = 0; temporary_k < MEMORY_COUNTER / 10; temporary_k++) { if(memory[temporary_n] == 0) printf("%3c%c%c%c%c%c",' ','+','0','0','0','0'); else printf("%8d",memory[temporary_n]); temporary_n++; } printf("
"); } } /// //carry exception of program void exception(ERROR error) { switch(error) { case EXCEPTION_INPUT_DATA: operationCode = HALT; printf("* * * the input data lsee than-9999 or more than 9999 * * *
"); break; case EXCEPTION_ERROR_DIVIDED: operationCode = HALT; printf("* * * the divide equal to zero * * *
"); break; case EXCEPTION_INSRUCTION: operationCode = HALT; printf("* * * the instruction error * * *
"); break; case EXCEPTION_OUT_ACCUMULATOR: operationCode = HALT; printf("* * * the accumulator is... * * *
"); break; case EXCEPTION_ERROR_OPERAND: operationCode = HALT; break; default: break; } //TODO } /// //interface of program void main(void) { while(1) //inorder to oher time to get instruction { enterInstruction(); // while(1) { loadRegister(); // translateInstruction(); // carryInstruction(); if(operationCode == HALT) // { computerDump(); // break; } } int i; printf("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
"); printf("* * * enter 1 to again. * * *
"); printf("* * * enter 0 to exit. * * *
"); scanf("%d",&i); if(i==0) break; } //TODO }