From e1dcd693bd821ba99a18062c02891fcbbbe3cba7 Mon Sep 17 00:00:00 2001 From: black Date: Thu, 10 Jul 2025 07:47:05 +0200 Subject: [PATCH] fixes and "slt" command added --- .gitignore | 2 ++ beispielprogramme/5.txt | 2 +- src/components/Alu.cpp | 34 ++++++++++++++++++---------------- src/components/Memory.cpp | 4 ++-- src/components/Register.cpp | 10 +++++++++- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 0df18e3..c95c988 100644 --- a/.gitignore +++ b/.gitignore @@ -220,4 +220,6 @@ fabric.properties # End of https://www.toptal.com/developers/gitignore/api/clion +/build + diff --git a/beispielprogramme/5.txt b/beispielprogramme/5.txt index 7af2c2d..7bba2cf 100644 --- a/beispielprogramme/5.txt +++ b/beispielprogramme/5.txt @@ -1,4 +1,4 @@ addi x1, x0, 5 # x1 = 5 (Zaehler) loop: addi x1, x1, −1 # x1 −= 1 -bne x1 , x0, loop # solange x1 != 0 , wiederhole \ No newline at end of file +bne x1, x0, loop # solange x1 != 0 , wiederhole \ No newline at end of file diff --git a/src/components/Alu.cpp b/src/components/Alu.cpp index 01559c5..e5eccb3 100644 --- a/src/components/Alu.cpp +++ b/src/components/Alu.cpp @@ -35,7 +35,7 @@ void Alu::calculate(const std::vector &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 &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(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(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; diff --git a/src/components/Memory.cpp b/src/components/Memory.cpp index 7471908..40dc0cb 100644 --- a/src/components/Memory.cpp +++ b/src/components/Memory.cpp @@ -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 diff --git a/src/components/Register.cpp b/src/components/Register.cpp index 3a21794..12d0bfb 100644 --- a/src/components/Register.cpp +++ b/src/components/Register.cpp @@ -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; }