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
|
||||
|
||||
/build
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
|
||||
if (commandVector.size() > 2) {
|
||||
if (commandVector.at(2).find('(') != std::string::npos) {
|
||||
arg2 = parseAddress(commandVector.at(2));
|
||||
} else {
|
||||
} else if (isRegister(commandVector.at(2))) {
|
||||
// Ansonsten wandle es in ein Registerargument um
|
||||
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
|
||||
// und führt zu undefiniertem Verhalten !!!
|
||||
// Speichert die Position des nächsten Befehls im angegebenen Register
|
||||
const auto pos = static_cast<int>(man.getNextStreamLineOffset().operator std::streamoff());
|
||||
reg.setRegister(arg1, pos);
|
||||
// Holt sich die Position des angegebenen labels und das Offset aus dem angegebenen Register
|
||||
const auto &label = commandVector.at(3);
|
||||
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) {
|
||||
const auto nextStreamLine = static_cast<int>(man.getNextStreamLineOffset().operator std::streamoff());
|
||||
reg.setRegister(arg1, nextStreamLine);
|
||||
// Erhöht die stream position (PC) um den angegebenen Wert
|
||||
for (int i = 1; i < arg2; ++i) {
|
||||
man.gotoNextStreamLine();
|
||||
}
|
||||
} else if (command == "j") {
|
||||
// Jump Befehl
|
||||
// Springe um den immediate value nach vorne (erhöhe den PC)
|
||||
for (int i = 1; i < arg1; i++) {
|
||||
man.gotoNextStreamLine();
|
||||
}
|
||||
// Springe zum angegebenen Label
|
||||
const auto &label = commandVector.at(1);
|
||||
const auto streamPos = pl.getStreamPosition(label);
|
||||
man.setStreamPosition(streamPos);
|
||||
} else if (command == "slli") {
|
||||
// Shift Left Logical Immediate Befehl
|
||||
const auto register1 = reg.getRegister(arg2);
|
||||
// Bitshifte den Wert aus Register1 mit dem immediate value
|
||||
const auto result = register1 << arg3;
|
||||
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 {
|
||||
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) {
|
||||
const auto immediate = std::stoi(argument.substr(0, pos + 1));
|
||||
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 0;
|
||||
|
||||
@@ -35,14 +35,14 @@ void Memory::dump(const int size) const {
|
||||
// Gib die Kopfzeile mit den Überschriften aus
|
||||
std::cout << COLOR_ADDRESS << "Adresse ";
|
||||
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";
|
||||
|
||||
for (int i = 0; i < size; i += valuesPerLine) {
|
||||
// Gebe die Überschrift für die einzelnen Blöcke mit dem entsprechenden Offset aus
|
||||
std::cout << COLOR_ADDRESS
|
||||
<< std::setw(6) << (i * sizeof(int))
|
||||
<< std::setw(6) << i
|
||||
<< ": " << COLOR_DEC;
|
||||
|
||||
// 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user