Write a program in Pep/9 assembly that matches the machine language program 4.37
ID: 3602400 • Letter: W
Question
Write a program in Pep/9 assembly that matches the machine language program 4.37. Take a screenshot.
this is 4.37 machine language, just in case.
;File: fig0437.peph Computer Systems, Fifth edition Figure 4.37 ;File: fig0437.pepb Computer Systems, Fifth edition ; Figure 4.37 0000 1101 0001 0000 0000 0001 1001 0003 1111 0001 0000 0000 0000 1001 0006 1100 0001 0000 0000 0001 0011 0009 0110 0001 0000 0000 0001 0101 000C 1001 0001 0000 0000 0001 0111 0000 D10019 Load byte accumulator 0003 F10009 ¡Store byte accumulator 0006 C10013 AExplanation / Answer
#include "code.h" #include "argument.h" #include "pep.h" #include "asm.h" #include #include // appendObjectCode void UnaryInstruction::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { objectCode.append(Pep::opCodeMap.value(mnemonic)); } } void NonUnaryInstruction::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { int instructionSpecifier = Pep::opCodeMap.value(mnemonic); if (Pep::addrModeRequiredMap.value(mnemonic)) { instructionSpecifier += Pep::aaaAddressField(addressingMode); } else { instructionSpecifier += Pep::aAddressField(addressingMode); } objectCode.append(instructionSpecifier); int operandSpecifier = argument->getArgumentValue(); objectCode.append(operandSpecifier / 256); objectCode.append(operandSpecifier % 256); } } void DotAddrss::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { int symbolValue = Pep::symbolTable.value(argument->getArgumentString()); objectCode.append(symbolValue / 256); objectCode.append(symbolValue % 256); } } void DotAlign::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { for (int i = 0; i getArgumentValue(); i++) { objectCode.append(0); } } } void DotAscii::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { int value; QString str = argument->getArgumentString(); str.remove(0, 1); // Remove the leftmost double quote. str.chop(1); // Remove the rightmost double quote. while (str.length() > 0) { Asm::unquotedStringToInt(str, value); objectCode.append(value); } } } void DotBlock::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { for (int i = 0; i getArgumentValue(); i++) { objectCode.append(0); } } } void DotBurn::appendObjectCode(QList &) { // Does not generate code. } void DotByte::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { objectCode.append(argument->getArgumentValue()); } } void DotEnd::appendObjectCode(QList &) { // Does not generate code. } void DotEquate::appendObjectCode(QList &) { // Does not generate code. } void DotWord::appendObjectCode(QList &objectCode) { if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { int value = argument->getArgumentValue(); objectCode.append(value / 256); objectCode.append(value % 256); } } void CommentOnly::appendObjectCode(QList &) { // Does not generate code. } void BlankLine::appendObjectCode(QList &) { // Does not generate code. } void UnaryInstruction::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); QString codeStr = QString("%1").arg(Pep::opCodeMap.value(mnemonic), 2, 16, QLatin1Char('0')).toUpper(); if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString mnemonStr = Pep::enumToMnemonMap.value(mnemonic); QString lineStr = QString("%1%2%3%4%5") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -7, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(mnemonStr, -8, QLatin1Char(' ')) .arg(" " + comment); Pep::memAddrssToAssemblerListing->insert(memAddress, assemblerListingList.size()); Pep::listingRowChecked->insert(assemblerListingList.size(), Qt::Unchecked); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(true); } void NonUnaryInstruction::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); int temp = Pep::opCodeMap.value(mnemonic); temp += Pep::addrModeRequiredMap.value(mnemonic) ? Pep::aaaAddressField(addressingMode) : Pep::aAddressField(addressingMode); QString codeStr = QString("%1").arg(temp, 2, 16, QLatin1Char('0')).toUpper(); QString oprndNumStr = QString("%1").arg(argument->getArgumentValue(), 4, 16, QLatin1Char('0')).toUpper(); if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString mnemonStr = Pep::enumToMnemonMap.value(mnemonic); QString oprndStr = argument->getArgumentString(); if (Pep::addrModeRequiredMap.value(mnemonic)) { oprndStr.append("," + Pep::intToAddrMode(addressingMode)); } else if (addressingMode == Enu::X) { oprndStr.append("," + Pep::intToAddrMode(addressingMode)); } QString lineStr = QString("%1%2%3%4%5%6%7") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -2) .arg(oprndNumStr, -5, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(mnemonStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); Pep::memAddrssToAssemblerListing->insert(memAddress, assemblerListingList.size()); Pep::listingRowChecked->insert(assemblerListingList.size(), Qt::Unchecked); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(true); } void DotAddrss::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); int symbolValue = Pep::symbolTable.value(argument->getArgumentString()); QString codeStr = QString("%1").arg(symbolValue, 4, 16, QLatin1Char('0')).toUpper(); if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString dotStr = ".ADDRSS"; QString oprndStr = argument->getArgumentString(); QString lineStr = QString("%1%2%3%4%5%6") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -7, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } void DotAlign::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { int numBytes = numBytesGenerated->getArgumentValue(); QString memStr = numBytes == 0 ? " " : QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); QString codeStr = ""; while ((numBytes > 0) && (codeStr.length() < 6)) { codeStr.append("00"); numBytes--; } if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString dotStr = ".ALIGN"; QString oprndStr = argument->getArgumentString(); QString lineStr = QString("%1%2%3%4%5%6") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -7, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { while (numBytes > 0) { codeStr = ""; while ((numBytes > 0) && (codeStr.length() < 6)) { codeStr.append("00"); numBytes--; } lineStr = QString(" %1").arg(codeStr, -7, QLatin1Char(' ')); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } } } void DotAscii::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); QString str = argument->getArgumentString(); str.remove(0, 1); // Remove the leftmost double quote. str.chop(1); // Remove the rightmost double quote. int value; QString codeStr = ""; while ((str.length() > 0) && (codeStr.length() < 6)) { Asm::unquotedStringToInt(str, value); codeStr.append(QString("%1").arg(value, 2, 16, QLatin1Char('0')).toUpper()); } if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString dotStr = ".ASCII"; QString oprndStr = argument->getArgumentString(); QString lineStr = QString("%1%2%3%4%5%6") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -7, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { while (str.length() > 0) { codeStr = ""; while ((str.length() > 0) && (codeStr.length() < 6)) { Asm::unquotedStringToInt(str, value); codeStr.append(QString("%1").arg(value, 2, 16, QLatin1Char('0')).toUpper()); } lineStr = QString(" %1").arg(codeStr, -7, QLatin1Char(' ')); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } } } void DotBlock::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); int numBytes = argument->getArgumentValue(); QString codeStr = ""; while ((numBytes > 0) && (codeStr.length() < 6)) { codeStr.append("00"); numBytes--; } if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString dotStr = ".BLOCK"; QString oprndStr = argument->getArgumentString(); QString lineStr = QString("%1%2%3%4%5%6") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -7, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); if ((Pep::burnCount == 0) || ((Pep::burnCount == 1) && (memAddress >= Pep::romStartAddress))) { while (numBytes > 0) { codeStr = ""; while ((numBytes > 0) && (codeStr.length() < 6)) { codeStr.append("00"); numBytes--; } lineStr = QString(" %1").arg(codeStr, -7, QLatin1Char(' ')); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } } } void DotBurn::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); QString symbolStr = symbolDef; if (symbolStr.length() > 0) { symbolStr.append(":"); } QString dotStr = ".BURN"; QString oprndStr = argument->getArgumentString(); QString lineStr = QString("%1 %2%3%4%5") .arg(memStr, -6, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } void DotByte::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); QString codeStr = QString("%1").arg(argument->getArgumentValue(), 2, 16, QLatin1Char('0')).toUpper(); if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString dotStr = ".BYTE"; QString oprndStr = argument->getArgumentString(); if (oprndStr.startsWith("0x")) { oprndStr.remove(2, 2); // Display only the last two hex characters } QString lineStr = QString("%1%2%3%4%5%6") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -7, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } void DotEnd::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); QString symbolStr = symbolDef; if (symbolStr.length() > 0) { symbolStr.append(":"); } QString dotStr = ".END"; QString lineStr = QString("%1 %2%3 %4") .arg(memStr, -6, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } void DotEquate::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString symbolStr = symbolDef; if (symbolStr.length() > 0) { symbolStr.append(":"); } QString dotStr = ".EQUATE"; QString oprndStr = argument->getArgumentString(); QString lineStr = QString(" %1%2%3%4") .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } void DotWord::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { QString memStr = QString("%1").arg(memAddress, 4, 16, QLatin1Char('0')).toUpper(); QString codeStr = QString("%1").arg(argument->getArgumentValue(), 4, 16, QLatin1Char('0')).toUpper(); if ((Pep::burnCount == 1) && (memAddress 0) { symbolStr.append(":"); } QString dotStr = ".WORD"; QString oprndStr = argument->getArgumentString(); QString lineStr = QString("%1%2%3%4%5%6") .arg(memStr, -6, QLatin1Char(' ')) .arg(codeStr, -7, QLatin1Char(' ')) .arg(symbolStr, -9, QLatin1Char(' ')) .arg(dotStr, -8, QLatin1Char(' ')) .arg(oprndStr, -12) .arg(comment); assemblerListingList.append(lineStr); listingTraceList.append(lineStr); hasCheckBox.append(false); } void CommentOnly::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { assemblerListingList.append(" " + comment); listingTraceList.append(" " + comment); hasCheckBox.append(false); } void BlankLine::appendSourceLine(QStringList &assemblerListingList, QStringList &listingTraceList, QList &hasCheckBox) { assemblerListingList.append(""); listingTraceList.append(""); hasCheckBox.append(false); } bool DotBlock::processFormatTraceTags(int &sourceLine, QString &errorString) { if (symbolDef.isEmpty()) { return true; } int pos = Asm::rxFormatTag.indexIn(comment); if (pos > -1) { QString formatTag = Asm::rxFormatTag.cap(0); Enu::ESymbolFormat tagType = Asm::formatTagType(formatTag); int multiplier = Asm::formatMultiplier(formatTag); if (argument->getArgumentValue() != Asm::tagNumBytes(tagType) * multiplier) { errorString = ";WARNING: Format tag does not match number of bytes allocated by .BLOCK."; sourceLine = sourceCodeLine; return false; } Pep::symbolFormat.insert(symbolDef, tagType); Pep::symbolFormatMultiplier.insert(symbolDef, multiplier); Pep::blockSymbols.append(symbolDef); } return true; } bool DotEquate::processFormatTraceTags(int &, QString &) { if (symbolDef.isEmpty()) { return true; } int pos = Asm::rxFormatTag.indexIn(comment); if (pos > -1) { QString formatTag = Asm::rxFormatTag.cap(0); Pep::symbolFormat.insert(symbolDef, Asm::formatTagType(formatTag)); Pep::symbolFormatMultiplier.insert(symbolDef, Asm::formatMultiplier(formatTag)); Pep::equateSymbols.append(symbolDef); } return true; } bool DotBlock::processSymbolTraceTags(int &sourceLine, QString &errorString) { // For global structs. if (symbolDef.isEmpty()) { return true; } if (Pep::blockSymbols.contains(symbolDef)) { return true; // Pre-existing format tag takes precedence over symbol tag. } int numBytesAllocated = argument->getArgumentValue(); QString symbol; QStringList list; int numBytesListed = 0; int pos = 0; while ((pos = Asm::rxSymbolTag.indexIn(comment, pos)) != -1) { symbol = Asm::rxSymbolTag.cap(1); if (!Pep::equateSymbols.contains(symbol)) { errorString = ";WARNING: " + symbol + " not specified in .EQUATE."; sourceLine = sourceCodeLine; return false; } numBytesListed += Asm::tagNumBytes(Pep::symbolFormat.value(symbol)) * Pep::symbolFormatMultiplier.value(symbol); list.append(symbol); pos += Asm::rxSymbolTag.matchedLength(); } if (numBytesAllocated != numBytesListed && numBytesListed > 0) { errorString = ";WARNING: Number of bytes allocated (" + QString("%1").arg(numBytesAllocated) + ") not equal to number of bytes listed in trace tag (" + QString("%1").arg(numBytesListed) + ")."; sourceLine = sourceCodeLine; return false; } Pep::blockSymbols.append(symbolDef); Pep::globalStructSymbols.insert(symbolDef, list); return true; } bool NonUnaryInstruction::processFormatTraceTags(int &, QString &) { if (mnemonic == Enu::CALL && argument->getArgumentString() == "malloc") { int pos = Asm::rxFormatTag.indexIn(comment); if (pos > -1) { QStringList list; QString formatTag = Asm::rxFormatTag.cap(0); Enu::ESymbolFormat tagType = Asm::formatTagType(formatTag); int multiplier = Asm::formatMultiplier(formatTag); QString symbolDef = QString("%1").arg(memAddress); // Dummy symbol for format tag in malloc if (!Pep::equateSymbols.contains(symbolDef)){ // Limitation: only one dummy format per program Pep::equateSymbols.append(symbolDef); } Pep::symbolFormat.insert(symbolDef, tagType); // Any duplicates have value replaced Pep::symbolFormatMultiplier.insert(symbolDef, multiplier); list.append(symbolDef); Pep::symbolTraceList.insert(memAddress, list); } } return true; } bool NonUnaryInstruction::processSymbolTraceTags(int &sourceLine, QString &errorString) { if (mnemonic == Enu::ADDSP || mnemonic == Enu::SUBSP) { int numBytesAllocated; if (addressingMode != Enu::I) { errorString = ";WARNING: Stack trace not possible unless immediate addressing is specified."; sourceLine = sourceCodeLine; return false; } numBytesAllocated = argument->getArgumentValue(); QString symbol; QStringList list; int numBytesListed = 0; int pos = 0; while ((pos = Asm::rxSymbolTag.indexIn(comment, pos)) != -1) { symbol = Asm::rxSymbolTag.cap(1); if (!Pep::equateSymbols.contains(symbol)) { errorString = ";WARNING: " + symbol + " not specified in .EQUATE."; sourceLine = sourceCodeLine; return false; } numBytesListed += Asm::tagNumBytes(Pep::symbolFormat.value(symbol)) * Pep::symbolFormatMultiplier.value(symbol); list.append(symbol); pos += Asm::rxSymbolTag.matchedLength(); } if (numBytesAllocated != numBytesListed) { QString message = (mnemonic == Enu::ADDSP) ? "deallocated" : "allocated"; errorString = ";WARNING: Number of bytes " + message + " (" + QString("%1").arg(numBytesAllocated) + ") not equal to number of bytes listed in trace tag (" + QString("%1").arg(numBytesListed) + ")."; sourceLine = sourceCodeLine; return false; } Pep::symbolTraceList.insert(memAddress, list); return true; } else if (mnemonic == Enu::CALL && argument->getArgumentString() == "malloc") { int pos = 0; QString symbol; QStringList list; while ((pos = Asm::rxSymbolTag.indexIn(comment, pos)) != -1) { symbol = Asm::rxSymbolTag.cap(1); if (!Pep::equateSymbols.contains(symbol) && !Pep::blockSymbols.contains(symbol)) { errorString = ";WARNING: " + symbol + " not specified in .EQUATE."; sourceLine = sourceCodeLine; return false; } list.append(symbol); pos += Asm::rxSymbolTag.matchedLength(); } if (!list.isEmpty()) { Pep::symbolTraceList.insert(memAddress, list); } return true; } else { return true; } }Related Questions
Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.