fixes and "slt" command added

This commit is contained in:
black
2025-07-10 07:47:05 +02:00
parent 35b434ec77
commit e1dcd693bd
5 changed files with 32 additions and 20 deletions

2
.gitignore vendored
View File

@@ -220,4 +220,6 @@ fabric.properties
# End of https://www.toptal.com/developers/gitignore/api/clion
/build

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}