fixes and "slt" command added
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -220,4 +220,6 @@ fabric.properties
|
|||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/clion
|
# End of https://www.toptal.com/developers/gitignore/api/clion
|
||||||
|
|
||||||
|
/build
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
addi x1, x0, 5 # x1 = 5 (Zaehler)
|
addi x1, x0, 5 # x1 = 5 (Zaehler)
|
||||||
loop:
|
loop:
|
||||||
addi x1, x1, −1 # x1 −= 1
|
addi x1, x1, −1 # x1 −= 1
|
||||||
bne x1 , x0, loop # solange x1 != 0 , wiederhole
|
bne x1, x0, loop # solange x1 != 0 , wiederhole
|
||||||
@@ -35,7 +35,7 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
|
|||||||
if (commandVector.size() > 2) {
|
if (commandVector.size() > 2) {
|
||||||
if (commandVector.at(2).find('(') != std::string::npos) {
|
if (commandVector.at(2).find('(') != std::string::npos) {
|
||||||
arg2 = parseAddress(commandVector.at(2));
|
arg2 = parseAddress(commandVector.at(2));
|
||||||
} else {
|
} else if (isRegister(commandVector.at(2))) {
|
||||||
// Ansonsten wandle es in ein Registerargument um
|
// Ansonsten wandle es in ein Registerargument um
|
||||||
arg2 = parseArgument(commandVector.at(2));
|
arg2 = parseArgument(commandVector.at(2));
|
||||||
}
|
}
|
||||||
@@ -159,31 +159,32 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
|
|||||||
// !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien
|
// !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien
|
||||||
// und führt zu undefiniertem Verhalten !!!
|
// und führt zu undefiniertem Verhalten !!!
|
||||||
// Speichert die Position des nächsten Befehls im angegebenen Register
|
// Speichert die Position des nächsten Befehls im angegebenen Register
|
||||||
const auto pos = static_cast<int>(man.getNextStreamLineOffset().operator std::streamoff());
|
const auto nextStreamLine = static_cast<int>(man.getNextStreamLineOffset().operator std::streamoff());
|
||||||
reg.setRegister(arg1, pos);
|
reg.setRegister(arg1, nextStreamLine);
|
||||||
// Holt sich die Position des angegebenen labels und das Offset aus dem angegebenen Register
|
// Erhöht die stream position (PC) um den angegebenen Wert
|
||||||
const auto &label = commandVector.at(3);
|
for (int i = 1; i < arg2; ++i) {
|
||||||
const auto streamPosLabel = pl.getStreamPosition(label);
|
|
||||||
const auto posOffset = reg.getRegister(arg2);
|
|
||||||
// Setzt die stream Position auf den gegebenen Wert & erhöht sie um den angegebenen Offset
|
|
||||||
man.setStreamPosition(streamPosLabel);
|
|
||||||
for (int i = 1; i < posOffset; ++i) {
|
|
||||||
man.gotoNextStreamLine();
|
man.gotoNextStreamLine();
|
||||||
}
|
}
|
||||||
} else if (command == "j") {
|
} else if (command == "j") {
|
||||||
// Jump Befehl
|
// Jump Befehl
|
||||||
// Springe um den immediate value nach vorne (erhöhe den PC)
|
// Springe zum angegebenen Label
|
||||||
for (int i = 1; i < arg1; i++) {
|
const auto &label = commandVector.at(1);
|
||||||
man.gotoNextStreamLine();
|
const auto streamPos = pl.getStreamPosition(label);
|
||||||
}
|
man.setStreamPosition(streamPos);
|
||||||
} else if (command == "slli") {
|
} else if (command == "slli") {
|
||||||
// Shift Left Logical Immediate Befehl
|
// Shift Left Logical Immediate Befehl
|
||||||
const auto register1 = reg.getRegister(arg2);
|
const auto register1 = reg.getRegister(arg2);
|
||||||
// Bitshifte den Wert aus Register1 mit dem immediate value
|
// Bitshifte den Wert aus Register1 mit dem immediate value
|
||||||
const auto result = register1 << arg3;
|
const auto result = register1 << arg3;
|
||||||
reg.setRegister(arg1, result);
|
reg.setRegister(arg1, result);
|
||||||
|
} else if (command == "slt") {
|
||||||
|
// Set less than Befehl
|
||||||
|
const auto register1 = reg.getRegister(arg2);
|
||||||
|
const auto register2 = reg.getRegister(arg3);
|
||||||
|
const auto lessThan = register1 < register2;
|
||||||
|
reg.setRegister(arg1, lessThan);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Befehl " << command << " wurde nicht gefunden!";
|
std::cerr << "\nBefehl " << command << " wurde nicht gefunden!\n" << std::flush;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +202,8 @@ int Alu::parseAddress(const std::string &argument) {
|
|||||||
if (const size_t pos = argument.find('('); pos != std::string::npos) {
|
if (const size_t pos = argument.find('('); pos != std::string::npos) {
|
||||||
const auto immediate = std::stoi(argument.substr(0, pos + 1));
|
const auto immediate = std::stoi(argument.substr(0, pos + 1));
|
||||||
const auto register1 = std::stoi(argument.substr(pos + 2));
|
const auto register1 = std::stoi(argument.substr(pos + 2));
|
||||||
const auto address = immediate + register1;
|
const auto register1Value = Register::getInstance().getRegister(register1);
|
||||||
|
const auto address = immediate + register1Value;
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ void Memory::dump(const int size) const {
|
|||||||
// Gib die Kopfzeile mit den Überschriften aus
|
// Gib die Kopfzeile mit den Überschriften aus
|
||||||
std::cout << COLOR_ADDRESS << "Adresse ";
|
std::cout << COLOR_ADDRESS << "Adresse ";
|
||||||
for (int i = 0; i < valuesPerLine; ++i) {
|
for (int i = 0; i < valuesPerLine; ++i) {
|
||||||
std::cout << " +" << std::setw(2) << i * sizeof(int) << " ";
|
std::cout << " +" << std::setw(2) << i << " ";
|
||||||
}
|
}
|
||||||
std::cout << COLOR_RESET << "\n";
|
std::cout << COLOR_RESET << "\n";
|
||||||
|
|
||||||
for (int i = 0; i < size; i += valuesPerLine) {
|
for (int i = 0; i < size; i += valuesPerLine) {
|
||||||
// Gebe die Überschrift für die einzelnen Blöcke mit dem entsprechenden Offset aus
|
// Gebe die Überschrift für die einzelnen Blöcke mit dem entsprechenden Offset aus
|
||||||
std::cout << COLOR_ADDRESS
|
std::cout << COLOR_ADDRESS
|
||||||
<< std::setw(6) << (i * sizeof(int))
|
<< std::setw(6) << i
|
||||||
<< ": " << COLOR_DEC;
|
<< ": " << COLOR_DEC;
|
||||||
|
|
||||||
// Gib die jeweiligen Werte der einzelnen Blöcke aus
|
// Gib die jeweiligen Werte der einzelnen Blöcke aus
|
||||||
|
|||||||
@@ -18,7 +18,15 @@ Register &Register::getInstance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Register::setRegister(const int reg, const int value) {
|
void Register::setRegister(const int reg, const int value) {
|
||||||
if (reg == 0) std::cerr << "Register 0 darf nicht beschrieben werden!";
|
if (reg == 0 && value != 0) {
|
||||||
|
std::cerr << "\nRegister 0 darf nicht beschrieben werden! Das geschriebene Register wird "
|
||||||
|
"auf 0 gesetzt. Dabei handelt es sich nicht unbedingt um einen Assembly "
|
||||||
|
"Fehler, \nes ist in den meisten Fällen nur dem Emulator Aufbau geschuldet. (Für den Beispielcode "
|
||||||
|
"4 z.B. ist dieser Fehler unbedenklich, es kann fortgefahren werden."
|
||||||
|
"\n" << std::flush;
|
||||||
|
m_registers[reg] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_registers.at(reg) = value;
|
m_registers.at(reg) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user