[CPPHTP7 NOTES] CH8. POINTERS(6) Simpletron Computer Simulator

(Exercise 8.18 Machine-Language Programming + Exercise 8.19 Computer Simulator)


Here comes the interesting part! I have created a virtual computer named Simpletron with C++! It is a simple machine that only has 100 memory locations, each can store a four digit signed decimal integers(-9999 to +9999). When running a program, the machine load the program to the start of its memory (location 00) and run the instruction stored in it one by one.


Although it is simple, we can still run program on it! Programs in Simpletron are witten in SML, which stands for Simpletron Machine Language. Each instruction written in SML occupies one memory location of Simpletron, thus, it is a signed four digit integer. The first two digits of each instruction are the operation code that specifies the operation to be performed(shown below). The last two digits are the operand, which are the address of the memory location. (Remember? There are 100 locations, which can be indexed 0 to 99)




Ok, now we have a brief knowledge of SML. We can try writing programs in SML now! (it is miserable, trust me XD)


The books provide some simple programs that can be written in SML. I have written down my programs below. Take a look at them if you are interested. You may also try to write a more complicated program yourself! You will miss C++ once you trying to program in SML though. LOL


Add sum until a negative number is entered

Location	Number	Instruction
00			+1011	Read N
01			+2011	Load N
02			+4110	Branch negative to 10
03			+2112	Store S
04			+1011	Read N
05			+2011	Load N
06			+4109	Branch negative to 09
07			+3012	Add S
08			+4003	Branch to 03
09			+1112	Write S			
10			+4300	Halt
11			+0000	Variable N
12			+0000	Variable S

Add sum of seven numbers

Location	Number	Instruction
00			+1011	Read N
01			+2012	Load S
02			+3011	Add N
03			+2112	Store S
04			+2013	Load I
05			+3114	Subtract One
06			+2113	Store I
07			+4209	Branch Zero to 09
08			+4000	Branch to 00
09			+1112	Write S			
10			+4300	Halt
11			+0000	Variable N
12			+0000	Variable S
13			+0007	Variable I
14			+0001	One

Find the largest number in N numbers

Location	Number	Instruction
00			+1018	Read N
01			+2018	Load N
02			+4217	Branch Zero to 17
03			+1019	Read Largest
04			+2018	Load N
05			+3121	Subtract One
06			+4216	Branch zero to 16
07			+2118	Store N
08			+2019	Load Largest
09			+1020	Read X
10			+3120	Subtract X
11			+4113	Branch negative to 13
12			+4004	Branch to 04
13			+2020	Load X
14			+2119	Store Largest
15			+4004	Branch to 04
16			+1119	Write Largest
17			+4300	Halt
18			+0000	Variable N
19			+0000	Variable Largest
20			+0000	Variable X
21			+0001	One

Okay, we have the program now. Wait! How do we run those programs? We don't have the Simpletron machine in reality! Don't be nervous, guys. I am going to show you how I write a Simpletron simulator with C++. Here is how it looks(the testing program is the same with the first one above):




The Simpletron machine has some register units to store neccessary information to run programs. We use an accumulator register to store the result of calculation, an instruction register to store the current instruction and a counter register to indicate the current location of execution. For example, when we need to add the integer at location 10 and the integer at location 11 together, we first load the first integer to the accumulator.(instruction:+2010) Then we add the second integer to the accumulator.(instruction:+3011) The result is now in the accumulator and we may store it at location 12 for later use.(instruction:+2112)  Note that after each instruction, the value in the counter register is increased by 1, which tells the computer to run the instruction at the next memory location.


I created a SimpletronSimulator class to represent the virtual computer. And I used a lot of static const int to represent the operation code in the table above so that I can recognize different operation with a switch easily. Okay, enough talk. The details are all in the sourcecode. I promise that is is a very easy and clear implementation!


// Exercise 8.19 Computer Simulator
#include <iostream>
#include <iomanip>

using namespace std;

// to simulate a type of computer called Simpletron
class SimpletronSimulator
{
public:
	SimpletronSimulator();
	void printConsoleMessage();
	void printErrorMessage();
	void inputSMLProgram();
	void executeSMLProgram();
	void printRegisterAndMemoryDump();

private:
	// memory
	static const int memorySize = 100;
	int memory[memorySize];
	bool setMemory( int index ); // false when -99999 sentinel is entered
	bool validInput( int input );
	// registers
	int accumulator;
	int instructionCounter;
	int instructionRegister;
	int operationCode;
	int operand;
	// operation code
	static const int READ = 10;
	static const int WRITE = 11;
	static const int LOAD = 20;
	static const int STORE = 21;
	static const int ADD = 30;
	static const int SUBTRACT = 31;
	static const int DIVIDE = 32;
	static const int MULTIPLY = 33;
	static const int BRANCH = 40;
	static const int BRANCHNEG = 41;
	static const int BRANCHZERO = 42;
	static const int HALT = 43;
};

int main()
{

	SimpletronSimulator simulator;
	simulator.printConsoleMessage();

	return 0;
}

SimpletronSimulator::SimpletronSimulator()
{
	accumulator = 0;
	instructionCounter = 0;

	for( int i=0; i<100; i++ )
	{
		memory[i] = 0;
	}
}

void SimpletronSimulator::printConsoleMessage()
{
	cout << "*** Welcome to Simpletron! ***" << endl;
	cout << "*** Please enter your program one instruction ***" << endl;
	cout << "*** (or data word) at a time. I will type the ***" << endl;
	cout << "*** location number and a question mark (?).  ***" << endl;
	cout << "*** You then type the word for that location. ***" << endl;
	cout << "*** Type the sentinel -99999 to stop entering ***" << endl;
	cout << "*** your program. ***" << endl << endl;

	inputSMLProgram();

	cout << endl;
	cout << "*** Program loading completed ***" << endl;
	cout << "*** Program execution begins  ***" << endl;

	executeSMLProgram();

	cout << "*** Program execution completed  ***" << endl;
	cout << endl;

	printRegisterAndMemoryDump();
}

void SimpletronSimulator::inputSMLProgram()
{
	bool inputContinue = true;
	for( int counter=0; inputContinue; counter++ )
		inputContinue = setMemory(counter); // setMemory return false when -99999 is entered
}

void SimpletronSimulator::executeSMLProgram()
{
	int temp; // for tempory use

	do
	{
		// load necessary data into registers
		instructionRegister = memory[instructionCounter];
		operationCode = instructionRegister / 100; // first two digits as code
		operand = instructionRegister % 100; // last two digits as location

		switch( operationCode )
		{
		case READ:
			cout << "? ";
			cin >> temp;
			memory[operand] = temp;
			instructionCounter++;
			break;
		case WRITE:
			cout << showpos << memory[operand] << endl;
			instructionCounter++;
			break;
		case LOAD:
			accumulator = memory[operand];
			instructionCounter++;
			break;
		case STORE:
			memory[operand] = accumulator;
			instructionCounter++;
			break;
		case ADD:
			accumulator += memory[operand];
			instructionCounter++;
			break;
		case SUBTRACT:
			accumulator -= memory[operand];
			instructionCounter++;
			break;
		case DIVIDE:
			accumulator /= memory[operand];
			instructionCounter++;
			break;
		case MULTIPLY:
			accumulator *= memory[operand];
			instructionCounter++;
			break;
		case BRANCH:
			instructionCounter = operand;
			break;
		case BRANCHNEG:
			if( accumulator < 0 )
			{
				instructionCounter = operand;
			}
			else
			{
				instructionCounter++;
			}
			break;
		case BRANCHZERO:
			if( accumulator == 0 )
			{
				instructionCounter = operand;
			}
			else
			{
				instructionCounter++;
			}
			break;
		case HALT:
			break;
		default:
			break;
		}
	}
	while( operationCode != HALT );
}

void SimpletronSimulator::printRegisterAndMemoryDump()
{
	cout << setfill('0') << internal; // fill 0 between '+' and number

	cout << "REGISTERS:" << endl;
	cout << "accumulator\t\t\t"
		<< showpos << setw(5) << accumulator << endl;
	cout << "instructionCounter\t\t   "
		<< noshowpos << setw(2) << instructionCounter << endl;
	cout << "instructionRegister\t\t"
		<< showpos << setw(5) << instructionRegister << endl;
	cout << "operationCode\t\t\t   "
		<< noshowpos << setw(2) << operationCode << endl;
	cout << "operand\t\t\t\t   " << setw(2) << operand << endl;

	cout << endl << "MEMORY:" << endl;
	cout << setfill(' ') << setw(2) <<' ';
	for( int i=0; i<=9; i++ ) // column number
		cout << ' ' << setw(5) << i;
	cout << endl;
	for( int i=0; i<=90; i+=10 ) // loop from 0 to 99
	{
		cout << noshowpos << setfill(' ') << setw(2) << i; // row number
		cout << setfill('0') << showpos; // formating
		for( int j=0; j<=9; j++ )
		{
			cout << ' ' << setw(5) << memory[i+j];
		}
		cout << endl;
	}
}

bool SimpletronSimulator::setMemory( int index )
{
	int input;
	cout << setfill('0');
	do // prompt again if not valid
	{
		cout << setw(2) << index << " ? ";
		cin >> input;
	}
	while( !validInput(input) );

	if( input == -99999 )
	{
		return false;
	}
	else
	{
		memory[index] = input;
		return true;
	}
}

bool SimpletronSimulator::validInput( int input )
{
	// valid when input is a 4-digit number or -99999 sentinel
	return ( ( input>=-9999 && input<=9999 ) || input==-99999 );
}

If you find any bugs or have any doubts, please feel free to contact me!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值