シンプルなSimpleTron(C言語実装、プログラム内部実装体験)
12236 ワード
簡単な紹介
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桁の数字はオペランド(アドレスコードとも呼ばれる)であり、操作するメモリ位置(データのアドレスであってもよいし、オペランドが転送コマンドの場合、オペランドはコマンドのアドレスであってもよい)である.すでに現代機械の指令によく似ているが、現代機械にはより多くのアドレス方式がある.二具体分析
オペレーションコードが表すオペレーション
入出力操作
読み込みと保存
さんじゅつえんざん
せいぎょてんい
メモリがあれば、命令を格納する場所があることは明らかですが、命令をどのように取得し、命令を分析処理して、命令の操作とデータ値を明確にするには、命令レジスタ(IR)を1つ必要とします(メモリから命令を取った後、命令レジスタを命令デコーダの操作コードの分析(ID)のために命令レジスタに置きます.
//命令レジスタの定義と初期化--メモリから命令を1つずつロードして保存する
//プログラムカウンタ:命令の統計が必要です(プログラムカウンタの本当の役割は、プログラムの実行順序を制御するための次の命令を指します)
//操作コードの定義と初期化
以上はメインレジスタの定義と初期化プログラムの前に必要なヒントで、出力します.
最後から2番目の文は-999999で入力を終了し、メモリなどを印刷する場合です.これは、命令やデータの格納位置をより明確にするために、メモリごとの状況を印刷し、アキュムレータや命令数などを明確にするためです(エラー時のデバッグが便利です).この部分はプログラム設計の最後の部分に置くことができ、説明に値する前の-4300はプログラム命令を停止し、メモリの位置は-9999より前であるべきであり、-9999は必要なプログラム制御であり、プログラム命令ではないので、命令カウント時に無視しなければならない.
次は関数定義です.
コマンドの入力
-99999で変数データを提示する入力に遭遇した場合
ロード、コマンドを1つずつ取得
めいれいかいせつ
オペレーションコードの取得方法
オペランドの取得方法
操作コードと操作数判断,if(operand<0 OR operand>99)に対して異常処理関数を呼び出す.
じっこうめいれい
これは大きなswitch文です
.
コンピュータコンテンツ印刷
例外処理
コード#コード#
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
}