Reputation: 1
Need help making a for loop, what I have is the c++ source code pasted to run simpleton in my Linux terminal.
// Exercise 8.16 Solution: ex08_16.cpp - Simpletron Simulator.
// simpletron.cpp
// g++ simpletron.cpp -o simpletron; ./simpletron
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
const size_t SIZE{100};
const int MAX_WORD{9999};
const int MIN_WORD{-9999};
const long SENTINEL{-99999};
enum class Command {READ = 10, WRITE, LOAD = 20, STORE, ADD = 30, SUBTRACT,
DIVIDE, MULTIPLY, BRANCH = 40, BRANCHNEG, BRANCHZERO, HALT};
// prototypes
void load(int* const);
void execute(int* const, int* const, size_t* const, int* const,
size_t* const, size_t* const);
void dump(const int* const, int, size_t, int, size_t, size_t);
bool validWord(int);
void output(string, int, int, bool);
int main() {
int memory[SIZE]{0};
int accumulator{0};
size_t instructionCounter{0};
size_t operationCode{0};
size_t operand{0};
int instructionRegister{0};
load(memory);
execute(memory, &accumulator, &instructionCounter,
&instructionRegister, &operationCode, &operand);
dump(memory, accumulator, instructionCounter, instructionRegister,
operationCode, operand);
}
// load instructions
void load(int* const loadMemory) {
long instruction;
size_t i{0}; // indexing variable
cout << "*** 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. ***\n"
<< "00 ? ";
cin >> instruction;
while (instruction != SENTINEL) {
if (!validWord(instruction)) {
cout << "Number out of range. Please enter again.\n";
}
else {
loadMemory[i++] = instruction;
}
// function setfill sets the padding character for unused
// field widths.
cout << setw(2) << setfill('0') << i << " ? ";
cin >> instruction;
}
}
// carry out the commands
void execute(int* const memory, int* const acPtr, size_t* const icPtr,
int* const irPtr, size_t* const opCodePtr, size_t* const opPtr) {
bool fatal{false};
int temp;
string messages[] = { "Accumulator overflow ***",
"Attempt to divide by zero ***",
"Invalid opcode detected ***" };
string termString =
"\n*** Simpletron execution abnormally terminated ***";
string fatalString = "*** FATAL ERROR: ";
cout << "\n************START SIMPLETRON EXECUTION************\n\n";
do
{
*irPtr = memory[*icPtr];
*opCodePtr = *irPtr / 100;
*opPtr = *irPtr % 100;
// switch to determine appropriate action
switch (static_cast<Command>(*opCodePtr)) {
case Command::READ:
cout << "Enter an integer: ";
cin >> temp;
while (!validWord(temp)) {
cout << "Number out of range. Please enter again: ";
cin >> temp;
}
memory[*opPtr] = temp;
++(*icPtr);
break;
case Command::WRITE:
cout << "Contents of " << setw(2) << setfill('0')
<< *opPtr << ": " << memory[*opPtr] << '\n';
++(*icPtr);
break;
case Command::LOAD:
*acPtr = memory[*opPtr];
++(*icPtr);
break;
case Command::STORE:
memory[*opPtr] = *acPtr;
++(*icPtr);
break;
case Command::ADD:
temp = *acPtr + memory[*opPtr];
if (!validWord(temp)) {
cout << fatalString << messages[0] << termString << '\n';
fatal = true;
}
else {
*acPtr = temp;
++(*icPtr);
}
break;
case Command::SUBTRACT:
temp = *acPtr - memory[*opPtr];
if (!validWord(temp))
{
cout << fatalString << messages[0] << termString << '\n';
fatal = true;
}
else
{
*acPtr = temp;
++(*icPtr);
}
break;
case Command::DIVIDE:
if (memory[*opPtr] == 0) {
cout << fatalString << messages[1] << termString << '\n';
fatal = true;
}
else {
*acPtr /= memory[*opPtr];
++(*icPtr);
}
break;
case Command::MULTIPLY:
temp = *acPtr * memory[*opPtr];
if (!validWord(temp)) {
cout << fatalString << messages[0] << termString << '\n';
fatal = true;
}
else {
*acPtr = temp;
++(*icPtr);
}
break;
case Command::BRANCH:
*icPtr = *opPtr;
break;
case Command::BRANCHNEG:
*acPtr < 0 ? *icPtr = *opPtr : ++(*icPtr);
break;
case Command::BRANCHZERO:
*acPtr == 0 ? *icPtr = *opPtr : ++(*icPtr);
break;
case Command::HALT:
cout << "*** Simpletron execution terminated ***\n";
break;
default:
cout << fatalString << messages[2] << termString << '\n';
fatal = true;
break;
}
} while (static_cast<Command>(*opCodePtr) != Command::HALT && !fatal);
cout << "\n*************END SIMPLETRON EXECUTION*************\n";
}
// print out name and content of each register and memory
void dump(const int* const memory, int accumulator,
size_t instructionCounter, int instructionRegister, size_t operationCode,
size_t operand) {
cout << "\nREGISTERS:\n";
output("accumulator", 5, accumulator, true);
output("instructionCounter", 2, instructionCounter, false);
output("instructionRegister", 5, instructionRegister, true);
output("operationCode", 2, operationCode, false);
output("operand", 2, operand, false);
cout << "\n\nMEMORY:\n";
cout << setfill(' ') << setw(3) << ' ';
// print header
for (int i{0}; i <= 9; ++i) {
cout << setw(5) << i << ' ';
}
for (int i{0}; i < SIZE; ++i) {
if (i % 10 == 0) {
cout << '\n' << setw(2) << i << ' ';
}
cout << internal << setw(5) << setfill('0')
<< memory[i] << ' ' << internal;
}
cout << endl;
}
// validate
bool validWord(int word) {
return word >= MIN_WORD && word <= MAX_WORD;
}
// display result
void output(string label, int width, int value, bool sign) {
// format of "accumulator", etc.
cout << setfill(' ') << left << setw(20) << label << ' ';
// is a +/- sign needed?
if (sign) {
cout << showpos << internal;
}
else {
cout << noshowpos;
}
// setup for displaying accumulator value, etc.
cout << left << setfill('0');
// determine the field widths and display value
if (width == 5) {
cout << setw(width) << value << '\n';
}
else { // width is 2
cout << setfill(' ') << setw(3) << ' ' << setw(width)
<< setfill('0') << value << '\n';
}
// disable sign if it was set
if (sign) {
cout << showpos << internal;
}
else {
cout << noshowpos;
}
}
/**************************************************************************
* (C) Copyright 1992-2017 by Deitel & Associates, Inc. and Prentice *
* Hall. All Rights Reserved. *
* *
* DISCLAIMER: The authors and publisher of this book have used their *
* best efforts in preparing the book. These efforts include the *
* development, research, and testing of the theories and programs *
* to determine their effectiveness. The authors and publisher make *
* no warranty of any kind, expressed or implied, with regard to these *
* programs or to the documentation contained in these books. The authors *
* and publisher shall not be liable in any event for incidental or *
* consequential damages in connection with, or arising out of, the *
* furnishing, performance, or use of these programs. *
*************************************************************************/
Here is an example of the code I tried to get a for-loop that counts to 10.
00 +2011 //loads the counter (location 11) into the accumulator
01 +2112 //stores value from accumulator into memory location 02
02 +1112 //outputs the current value
03 +2011 //loads the counter (location 11) into accumulator
04 +3013 //adds 1 (memory location 13)
05 +2111 //stores the updated counter back into memory location 11
06 +2011 //loads the counter (memory location 11) into accumulator
07 +3114 //subtract 10 from location 14
08 +4100 //if result 0, halt
09 +4000 //branch to the start of the loop (memory location 00)
10 +4300 //halt program
11 +0001 //initial counter value
12 +0000 //stored value
13 +0001 //increment value (1)
14 +0010 //loop end value
15 -99999 //exits program and runs
However, when I run this program, my result ends up counting up from 1 to 9999 in memory location 12. My thinking is it could be the result of having memory 12 as a stored value so I might not need it?
.....
Contents of 12: 9989
Contents of 12: 9990
Contents of 12: 9991
Contents of 12: 9992
Contents of 12: 9993
Contents of 12: 9994
Contents of 12: 9995
Contents of 12: 9996
Contents of 12: 9997
Contents of 12: 9998
Contents of 12: 9999......
*** FATAL ERROR: Accumulator overflow ***
*** Simpletron execution abnormally terminated ***
Upvotes: 0
Views: 64
Reputation: 365467
+4100
jumps to 00
if the last result was negative. It can't jump to your halt. Then +4000
unconditionally jumps to the same place, so the +4100
instruction might as well have not been there. You want a different destination for your conditional branch.
(Or better, replace those two branches with one branch that either jumps to the top while you should keep looping, or falls through to the halt. In asm, normal loops look like a do{}while()
so there's only one branch and it's a conditional.)
I'm assuming without checking the interpreter source code that the machine-code numbers are parsed as hex, with the most significant byte being the opcode from the enum{ ..., BRANCH = 40, BRANCHNEG, BRANCHZERO, HALT}
which means
40
= unconditional branch41
= branch if negative42
= branch if zero43
= haltUpvotes: 1