I'm in the process of implementing a MIPS instruction set simulator. But when I try compiling my code, I keep getting "out of scope" errors and it's getting to be very frustrating. I've tried all kinds of variations, but nothing seems to be helping.
Here's my MIPSsim.cpp file#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
using namespace std;
const int BITS = 32;
string inst_decode(string line);
void execute(string line, string instruction, int ®isters[]);
void print(int cycle, int inst_address, int regs[]/*, int data[]*/);
int convert_5(string binary);
int convert_32(string binary);
void add(string line, int ®isters[]);
void sub(string line, int ®isters[]);
void mult(string line, int ®isters[]);
string inst_decode(string line){
string instruction;
if(line.compare(0,1,"0") == 0){
if (line.compare(1,5,"00010") == 0){
cout << "JUMP" << endl;
instruction = "JUMP";
}else if (line.compare(1,5,"00100") == 0){
cout << "BEQ" << endl;
instruction = "BEQ";
}else if (line.compare(1,5,"00001") == 0){
cout << "BLTZ" << endl;
instruction = "BLTZ";
}else if (line.compare(1,5,"00111") == 0){
cout << "BGTZ" << endl;
instruction = "BGTZ";
}else if (line.compare(1,5,"01011") == 0){
cout << "SW" << endl;
instruction = "SW";
}else if (line.compare(1,5,"00011") == 0){
cout << "LW" << endl;
instruction = "LW";
}else if (line.compare(1,5,"00010") == 0){
cout << "SRL" << endl;
instruction = "SRL";
}else if ((line.compare(1,5,"11100") == 0)&&(line.compare(26,6,"000010") == 0)){
cout << "MUL" << endl;
instruction = "MUL";
}else if (line.compare(1,5,"00000") == 0){
if (line.compare(26,6,"100000") == 0){
cout << "ADD" << endl;
instruction = "ADD";
}else if (line.compare(26,6,"100010") == 0){
cout << "SUB" << endl;
instruction = "SUB";
}else if (line.compare(26,6,"100100") == 0){
cout << "AND" << endl;
instruction = "AND";
}else if (line.compare(26,6,"100101") == 0){
cout << "OR" << endl;
instruction = "OR";
}else if (line.compare(26,6,"101010") == 0){
cout << "SLT" << endl;
instruction = "SLT";
}else if (line.compare(26,6,"000000") == 0){
cout << "SLL" << endl;
instruction = "SLL";
}else if (line.compare(6,26,"00000000000000000000000000") == 0){
cout << "NOP" << endl;
instruction = "NOP";
}
}
}else{
if (line.compare(26,6,"100100") == 0){
cout << "ADDI" << endl;
instruction = "ADDI";
}else if (line.compare(26,6,"100010") == 0){
cout << "ANDI" << endl;
instruction = "ANDI";
}
}
return instruction;
}
void execute(string line, string instruction, int& registers[]){
if(instruction == "ADD"){
add(line, registers);
}else if(instruction == "ADDI"){
addi(line, registers);
}else if(instruction == "SUB"){
sub(line, registers);
}else if(instruction == "MUL"){
mult(line, registers);
}
}
void print(int cycle, int inst_address, int regs[]/*, int data[][]*/){
cout << "---------------------------\n";
cout << "Cycle: " << cycle << "\t" << inst_address << "\t" << "\n";
cout << "\nRegisters\n";
cout << "R00:\t";
for(int i=0; i<=15; i++){
cout << regs[i] << "\t";
}
cout << "\nR16:\t";
for(int i=16; i<32; i++){
cout << regs[i] << "\t";
}
cout << "\n\nData\n";
//cout << "\n148:\t";
//for(int i=0; i<8; i++){
// cout << data[i] << "\t";
//}
//cout << "\n180:\t";
//for(int i=9; i<17; i++){
// cout << data[i] << "\t";
//}
//cout << "\n212:\t";
//for(int i=18; i<26; i++){
// cout << data[i] << "\t";
//}
cout << "\n";
}
int main(){
int registers[32] = {0};
// int data[2][32];
string inst;
//int cycle = 1;
//int PC = 64;
string binary_inst[64];
ifstream inFile;
inFile.open("sample.txt");
if (!inFile) {
cout << "Unable to open file sample.txt" << endl;
return 0;
}
string x;
while(!inFile.eof()){
for(int i=0; i<64; i++){
inFile >> x;
binary_inst[i] = x;
inst = inst_decode(binary_inst[i]);
execute(binary_inst[i], inst, registers);
//print(cycle, PC, registers);
}
}
// print(cycle, PC, registers);
return 0;
}
int convert_5(string binary) {
long power = 32;
long sum = 0;
assert(binary.size() == 5);
for ( int i=0; i<BITS; ++i) {
if ( i==0 && binary[i]!='0') {
sum = -32;
}
else {
sum += (binary[i]-'0')*power;
}
power /= 2;
}
return sum;
}
int convert_32(string binary) {
long power = 4294967296;
long sum = 0;
assert(binary.size() == 32);
for ( int i=0; i<BITS; ++i) {
if ( i==0 && binary[i]!='0') {
sum = -4294967296;
}
else {
sum += (binary[i]-'0')*power;
}
power /= 2;
}
return sum;
}
void add(string line, int& registers[]){
int dest = convert_5(line.substr(17,5));
cout << "Dest: " << dest << endl;
int target = convert_5(line.substr(12,5));
cout << "Target: " << target << endl;
int source = convert_5(line.substr(7,5));
cout << "Source: " << source << endl;
registers[dest] = registers[source] + registers[target];
cout << "Addition: " << registers[dest] << endl;
}
void sub(string line, int& registers[]){
int dest = convert_5(line.substr(17,5));
cout << "Dest: " << dest << endl;
int target = convert_5(line.substr(12,5));
cout << "Target: " << target << endl;
int source = convert_5(line.substr(7,5));
cout << "Source: " << source << endl;
registers[dest] = registers[source] - registers[target];
cout << "Subtraction: " << registers[dest] << endl;
}
void mult(string line, int& registers[]){
int dest = convert_5(line.substr(17,5));
cout << "Dest: " << dest << endl;
int target = convert_5(line.substr(12,5));
cout << "Target: " << target << endl;
int source = convert_5(line.substr(7,5));
cout << "Source: " << source << endl;
registers[dest] = registers[source] * registers[target];
cout << "Multiplication: " << registers[dest] << endl;
}
Here are the error messages I keep getting:
lin114-08:10% make all
g++ -Wall -o MIPSsim MIPSsim.cpp
MIPSsim.cpp:10: error: declaration of ‘registers’ as array of references
MIPSsim.cpp:14: e开发者_如何学编程rror: declaration of ‘registers’ as array of references
MIPSsim.cpp:15: error: declaration of ‘registers’ as array of references
MIPSsim.cpp:16: error: declaration of ‘registers’ as array of references
MIPSsim.cpp:85: error: declaration of ‘registers’ as array of references
MIPSsim.cpp: In function ‘void execute(...)’:
MIPSsim.cpp:86: error: ‘instruction’ was not declared in this scope
MIPSsim.cpp:87: error: ‘line’ was not declared in this scope
MIPSsim.cpp:87: error: ‘registers’ was not declared in this scope
MIPSsim.cpp:89: error: ‘line’ was not declared in this scope
MIPSsim.cpp:89: error: ‘registers’ was not declared in this scope
MIPSsim.cpp:89: error: ‘addi’ was not declared in this scope
MIPSsim.cpp:91: error: ‘line’ was not declared in this scope
MIPSsim.cpp:91: error: ‘registers’ was not declared in this scope
MIPSsim.cpp:93: error: ‘line’ was not declared in this scope
MIPSsim.cpp:93: error: ‘registers’ was not declared in this scope
MIPSsim.cpp: In function ‘int main()’:
MIPSsim.cpp:146: warning: cannot pass objects of non-POD type ‘struct std::string’ through ‘...’; call will abort at runtime
MIPSsim.cpp:146: warning: cannot pass objects of non-POD type ‘struct std::string’ through ‘...’; call will abort at runtime
MIPSsim.cpp: At global scope:
MIPSsim.cpp:193: error: declaration of ‘registers’ as array of references
MIPSsim.cpp: In function ‘void add(...)’:
MIPSsim.cpp:194: error: ‘line’ was not declared in this scope
MIPSsim.cpp:203: error: ‘registers’ was not declared in this scope
MIPSsim.cpp: At global scope:
MIPSsim.cpp:207: error: declaration of ‘registers’ as array of references
MIPSsim.cpp: In function ‘void sub(...)’:
MIPSsim.cpp:208: error: ‘line’ was not declared in this scope
MIPSsim.cpp:217: error: ‘registers’ was not declared in this scope
MIPSsim.cpp: At global scope:
MIPSsim.cpp:221: error: declaration of ‘registers’ as array of references
MIPSsim.cpp: In function ‘void mult(...)’:
MIPSsim.cpp:222: error: ‘line’ was not declared in this scope
MIPSsim.cpp:231: error: ‘registers’ was not declared in this scope
make: *** [MIPSsim] Error 1
Any help would be greatly appreciated
Always fix the first error the compiler gives you: int ®isters[]
won't work - use int * registers
or int registers[]
.
If you really want a reference to an array, you need to specify the size:
void execute(string line, string instruction, int (®isters) [10]);
All of these approaches will let you modify the actual array you pass to the function - there's no copying.
Side note:
In MIPSsim.cpp
line 146 you're trying to pass a std::string
to a vararg function (e.g. sprintf
or printf
) - That won't work. Pass string.c_str()
instead.
I can't say if there are other problems but I think your execute
, add
, sub
, mult
functions can just take registers
as an array, not an array of references.
void add(string line, int registers[]);
You can't pass an array as an argument in C++. What you'd have to do is declare the parameters:
int (®isters)[32];
But registers aren't the only machine state which is likely to be changed by executing some code. A much better solution would be to define a struct with all of the machine state (except maybe the memory):
struct HWState
{
int registers[32];
unsigned cc;
??? pc;
// ...
};
Then pass that by reference, and you shouldn't have any problem. (In practice, C style arrays should only be used for static variables, with static initialization, and as members, when the count is constant and not too big.)
When you have a lot of functions that all take the same argument, that's usually a sign that they should be member functions. Here, you have add
, sub
and mult
which all operate on your set of registers. And of course, most future instructions will too.
Therefore, define a class CPU
with data members for each register (i.e. int r[32];float f[32];
, and a method CPU::add(std::string line)
. Within add, you can just refer to r[4]
if you need the first function argument register etc.
精彩评论