Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <list>
- #include <iterator>
- #include <string>
- #include <fstream>
- #include <regex>
- #include <map>
- #include <cstring>
- #include <sstream>
- #include <bitset>
- using namespace std;
- typedef unsigned char byte;
- typedef struct symb {
- int id;
- string name;
- int offset;
- string value;
- string sect_name;
- string type;
- string pc_relative;
- } symbol;
- typedef struct sect {
- string name;
- string size;
- vector<symbol> symbols;
- } section;
- //sp //pc //psw
- const vector<string> register_masks = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1111"};
- const vector<string> register_array = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "psw"};
- const vector<string> adressing_masks = {"000", "001", "010", "011", "100", "101"};
- const vector<string> zero_operand_masks = {"00001", "11000", "11001"};
- const vector<string> zero_operand_instr = {"halt", "ret", "iret"};
- const vector<string> one_operand_masks = {"00011", "01010", "10001", "10010", "10011", "10100", "10101", "10110",
- "10111"};
- const vector<string> one_operand_instr = {"int", "not", "push", "pop", "jmp", "jeq", "jne", "jgt", "call"};
- const vector<string> two_operand_masks = {"00010", "00100", "00101", "00111", "01000", "01001", "01011", "01100",
- "01101", "01110", "01111", "10000"};
- const vector<string> two_operand_instr = {"xchg", "mov", "add", "sub", "mul", "div", "cmp", "and", "or", "xor", "test",
- "shl", "shr"};
- const vector<string> operand_types = {".global", ".extern"};
- const vector<string> section_types = {".text", ".data", ".bss"};
- const vector<string> other_options = {".word", ".byte", ".char", ".long"};
- int howManyOp = 0;
- string tempInstr = "";
- static int id = 0;
- vector<symbol> symbolTable, tempSymbTable;
- vector<section> sectionTable;
- string tempString, tempOp1, tempOp2, tempElem, tempSymbType = "local", tempSection = "UND";
- string codeFirst, codeSecond, tempLineCode = "";
- string byteORword = "1";
- string getRegisterMask(string reg) {
- if (reg == "psw") return register_masks[8];
- if (reg == "sp") return register_masks[6];
- if (reg == "pc") return register_masks[7];
- int i;
- for (i = 0; i < 9; i++) {
- if (register_array[i] == reg) return register_masks[i];
- }
- return "greska";
- }
- string getSection(string sect) {
- int i;
- for (i = 0; i < 3; i++) {
- if (section_types[i] == sect) return section_types[i];
- }
- return "greska";
- }
- string getInstructionMask(string instr) {
- int i;
- for(i = 0; i < 3; i++) {
- if (zero_operand_instr[i] == instr) {
- howManyOp = 0;
- return zero_operand_masks[i];
- }
- }
- for (i = 0; i < 9; i++) {
- if (one_operand_instr[i] == instr) {
- howManyOp = 1;
- return one_operand_masks[i];
- }
- }
- for(i = 0; i < 12; i++) {
- if (two_operand_instr[i] == instr) {
- howManyOp = 2;
- return two_operand_masks[i];
- }
- }
- return "greska";
- }
- int getInstructionBytes(string instr) {
- // if (instr == ".char") return 1;
- if (instr == ".byte") return 1;
- if (instr == ".word") return 2;
- // if (instr == ".long") return 4;
- return -1;
- }
- int isNumber(string line) {
- int i;
- for (i = 0; i < line.length(); i++) {
- if (line[i] < '0' || line[i] > '9') return -1;
- }
- cout << "jeste br" ;
- return 0;
- }
- int isHexNumber(string line) {
- if(line[0] == '0' && line[1] == 'x') return 0;
- return -1;
- }
- string convertToBin(string value, int sendBits) {
- cout << value;
- int intOrHex = isNumber(value) != -1 ? 10 : 16;
- stringstream ss;
- unsigned n;
- cout<<"convert" << endl;
- ss << hex << stoi(value, nullptr, intOrHex);
- ss >> n;
- cout << "usli u convert to bin" << endl;
- int numBitset = sendBits;
- // (sendBits != 0) ? sendBits : (value.length() == 6 ? 16 : 8) ;
- if(sendBits == 8 || intOrHex == 10) {
- cout << "usli u number 8" << endl;
- bitset<8> b(n);
- cout << b.to_string() << endl;
- return b.to_string();
- }
- else {
- bitset<16> b1(n);
- string changeBytes = b1.to_string();
- changeBytes = changeBytes.substr(8) + changeBytes.substr(0,8);
- return changeBytes;
- }
- // outputs "00000000000000000000000000001010"
- // cout << b.to_string() << endl;
- }
- string addSymbol(string symb, int twoBytes) {
- int i;
- string tempValue = "UND";
- for (i = 0; i < symbolTable.size(); i++) {
- if (symbolTable[i].name == symb) {
- cout << "simbol vrednost" << symbolTable[i].name;
- tempValue = symbolTable[i].value;
- break;
- }
- }
- cout << endl;
- cout << tempValue << "TEMP VALUE";
- if (tempValue != "UND") {
- return convertToBin(tempValue, twoBytes == 1 ? 16 : 8);
- } else {
- symbol symbNew;
- symbNew.id = id++;
- symbNew.name = symb;
- symbNew.sect_name = "UND";
- symbNew.offset = 0; //mesto u sekciji
- symbNew.value = "-1";
- symbNew.type = tempSymbType;
- symbNew.pc_relative = '0';
- symbolTable.push_back(symbNew);
- return twoBytes == 1 ? "1111111111111111" : "11111111";
- }
- }
- string findOperandMask(string oper, int numOfOper) {
- cout << "usli u find operand" << oper << endl;
- string operCut = oper.length() > 1 && (oper[2] == 'l' || oper[2] == 'h') ? oper.substr(1) : oper;
- //registarsko direktno
- cout << "usli u find operand" << endl;
- if(getRegisterMask(operCut) != "greska") {
- cout << "reg dir" << endl;
- return "001" + getRegisterMask(operCut) + (oper[2] == 'h' ? "1" : "0");
- }
- else {
- cout << "usli u else znaci nije reg dir" << endl;
- //neposredno adresiranje
- if((numOfOper == 2 && howManyOp ==2) || tempInstr == "push") {
- cout << "neposredno" << endl;
- if(oper[0] == '&') {
- return "00000000" + addSymbol(oper.substr(1), 0);
- }
- else {
- cout <<"else neposredno"<< endl;
- if(isHexNumber(oper) != -1 || isNumber(oper) != -1){
- return "00000000" + convertToBin(oper, isNumber(oper) == -1 ? 8 : 16);
- }
- }
- }
- //pc relativno i imamo samo simbol
- if(oper[0] == '$') {
- return "10100000" + addSymbol(oper.substr(1), 1);
- }
- //memorijsko apsolutno
- if(oper[0] == '*') {
- return "10100000" + convertToBin(oper.substr(1), 16);
- }
- cout << "ispred reg ind";
- if(oper.find('[') != -1 && oper.find(']') != -1) {
- cout << "Sa [ ] " << endl;
- string operMove = oper.substr(oper.find('[') + 1, oper.find(']') - oper.find('[') - 1);
- cout << "MOVE "<< operMove << endl;
- if(operMove != "0") {
- //registarsko indirektno sa 8/16 bitnim pomerajem
- if(isHexNumber(operMove) != -1 || isNumber(operMove) != -1){
- return (isNumber(operMove) != -1 ? "011" : "100") + convertToBin(operMove, isNumber(operMove) != -1 ? 8 : 16);
- }
- else {
- // za sad sam samo sa obuhvatila 8 bitno reg ind sa simbolom
- return "011" + convertToBin(operMove, isNumber(operMove) == -1 ? 8 : 16);
- }
- }
- else {
- //posto je 0 pomeraj onda je registarsko indirektno bez pomeraja
- return "010" + getRegisterMask(operCut) + oper[2] == "h" ? "1" : "0";
- }
- }
- //memorijsko samo sa simbolom
- cout << isHexNumber(oper) << " hexa " << isNumber(oper) << " number \n";
- if(isHexNumber(oper) == -1 && isNumber(oper) == -1) {
- cout << "memorisko samo sa simbolom" << oper << endl;
- return "10100000" + addSymbol(oper, 1);
- }
- }
- cout << "OPERAND KOJI JE GRESKA " << oper << endl;
- return "greska";
- }
- string findOperand(string operandsString) {
- cout << operandsString << " operands" << howManyOp << endl;
- if(howManyOp == 2) {
- if(operandsString.find(',') == -1) {
- cout << "Greska, moraju 2 operanda!!" << endl;
- return "greska";
- }
- cout << operandsString << "usli smo u dodelu";
- string op1, op2, op1Mask, op2Mask;
- op1 = operandsString.substr(0, operandsString.find(','));
- op2 = operandsString.substr(operandsString.find(',') + 1);
- cout << "op1 " << op1 << " op2" << op2 << endl;
- op1Mask = findOperandMask(op1, 1);
- cout << "prva maska" << op1Mask << "op2 " << op2<< "evo" << endl;
- op2Mask = findOperandMask(op2, 2);
- cout << "druga maska" << op2Mask << endl;
- return op1Mask + op2Mask;
- }
- else {
- return findOperandMask(operandsString, 1);
- }
- }
- string convertStringToHex(string finalCode) {
- int i = 0, j = 0;
- string part = "", whole = "";
- cout << finalCode.length();
- for(i = 0; i+4 <= finalCode.length() + 1;) {
- cout << "usli u for" << whole << endl;
- if(j % 2 == 0 && j != 0) whole += " ";
- part = finalCode.substr(i, 4);
- cout << part << "i=" << i <<endl;
- int until= i+4 ;
- i+=4;
- j++;
- if(part == "0000") {
- whole += "0";
- // continue;
- }
- if(part == "0001") {
- whole += "1";
- // continue;
- }
- if(part == "0010") {
- whole += "2";
- // continue;
- }
- if(part == "0011") {
- whole += "3";
- // continue;
- }
- if(part == "0100") {
- whole += "4";
- // continue;
- }
- if(part == "0101") {
- whole += "5";
- // continue;
- }
- if(part == "0110") {
- whole += "6";
- // continue;
- }
- if(part == "0111") {
- whole += "7";
- // continue;
- }
- if(part == "1000") {
- whole += "8";
- // continue;
- }
- if(part == "1001") {
- whole += "9";
- // continue;
- }
- if(part == "1010") {
- whole += "A";
- // continue;
- }
- if(part == "1011") {
- whole += "B";
- // continue;
- }
- if(part == "1100") {
- whole += "C";
- // continue;
- }
- if(part == "1101") {
- whole += "D";
- // continue;
- }
- if(part == "1110") {
- whole += "E";
- // continue;
- }
- if(part == "1111") {
- whole += "F";
- // continue;
- }
- // switch(part) {
- // case "0000":
- // whole += "0";
- // break;
- // case "0001":
- // whole += "1 ";
- // break;
- // case "0010":
- // whole += "2";
- // break;
- // case "0011":
- // whole += "3";
- // break;
- // case "0100":
- // whole += "4";
- // break;
- // case "0101":
- // whole += "5";
- // break;
- // case "0101":
- // whole += "6";
- // break;
- // case "0111":
- // whole += "7";
- // break;
- // case "1000":
- // whole += "8";
- // break;
- // case "1001":
- // whole += "9";
- // break;
- // case "1010":
- // whole += "A";
- // break;
- // case "1011":
- // whole += "B";
- // break;
- // case "1100":
- // whole += "C";
- // break;
- // case "1101":
- // whole += "D";
- // break;
- // case "1110":
- // whole += "E";
- // break;
- // case "1111":
- // whole += "F";
- // break;
- // default:
- // whole+= "";
- // }
- }
- return whole;
- }
- int main() {
- // string tempString, tempOp1, tempOp2, tempElem, tempSymbType = "local", tempSection = "UND";
- // string codeFirst, codeSecond, tempLineCode = "";
- // string byteORword = "1";
- int i;
- symbol symbNew;
- section sectNew;
- int allOffset = 0xff00, sectionOffset = 0;
- // ifstream inFile("C:\Users\Antoanea\Desktop\test.txt");
- // ifstream inFile("/home/marko95/JetBrains/Projects/ClionProjects/SSAsembler/test1.txt");
- ifstream inFile("C:/Users/Antoanea/Desktop/c++/test.txt");
- string line;
- if (!inFile.is_open()) {
- cout << "file not exists";
- exit(1);
- }
- while (getline(inFile, line)) {
- if (line == ".end") {
- sectNew.name = tempSection;
- sectNew.size = sectionOffset;
- sectNew.symbols = tempSymbTable;
- sectionTable.push_back(sectNew);
- cout << "kraj fajla";
- break;
- }
- int isComment = line.find('@') != -1 ? line.find('@') : line.find(';');
- if (isComment != -1) {
- if (isComment == 0) continue;
- line = line.substr(0, isComment);
- }
- while (!line.empty()) {
- cout << '\n' << line << " THIS IS LINE \n";
- tempString = line.find(' ') != -1 ? line.substr(0, line.find(' ')) : line; //trenutna rec
- cout << tempString << '\n';
- // if(tempString == "") continue;
- line = line.substr(line.find(' ') + 1);
- if (tempString == ".global" || tempString == ".extern") {
- if (tempSection != "UND") {
- printf("Greska ne moze gobal posle sekcije");
- return 1;
- }
- tempSymbType = "global";
- while (!line.empty()) {
- tempElem = line.substr(0, line.find(','));
- cout << tempElem;
- line = line.substr(line.find(',') + 1);
- symbNew.id = id++;
- symbNew.name = tempElem;
- symbNew.sect_name = tempSection;
- symbNew.offset = 0; //mesto u sekciji
- symbNew.value = "-1";
- symbNew.type = tempSymbType;
- symbNew.pc_relative = '0';
- symbolTable.push_back(symbNew);
- cout << tempElem;
- if (tempElem == line) line = "";
- }
- } else {
- cout << tempString << " nije global"<< "\n";
- if (getSection(tempString) != "greska" || tempString == ".section") {
- cout << "sekcija";
- //ako vec postoji neka sekcija ubacujemo je u niz sekcija
- if (tempSection != "UND") {
- sectNew.name = tempSection;
- sectNew.size = sectionOffset;
- sectNew.symbols = tempSymbTable;
- sectionTable.push_back(sectNew);
- }
- //ako je sekcija sa bilo kojim imenom moramo da dohvatimo ime sekcije
- if (tempString == ".section") {
- line = line.substr(line.find(' ') + 1);
- tempString = "." + line;
- }
- //dodajemo novu sekciju u tabelu simbola
- tempSection = tempString.substr(1);
- symbNew.id = id++;
- symbNew.name = tempSection;
- symbNew.sect_name = tempSection;
- symbNew.offset = 0; //mesto u sekciji
- symbNew.value = allOffset;
- symbNew.type = tempSymbType;
- symbNew.pc_relative = '0';
- symbolTable.push_back(symbNew);
- line = "";
- tempSymbTable = {};
- sectionOffset = 0;
- } else {
- cout << "Nije sekcija";
- cout << line << "tempS" << tempString << endl;
- // cout << "Nije sekcija \n" << line << " aa";
- if (tempSection == "UND") {
- // printf("%s \n", line);
- printf("Ne mogu instrukcije i labele pre prve sekcije");
- return 2;
- }
- if (tempString.find(':') != -1) {
- tempElem = tempString.substr(0, tempString.find(':'));
- cout << tempString << tempElem << " Nasli smo labelu\n";
- cout << "\n LINE" << line << "tempString" << tempString << "\n";
- tempString = line.find(' ') != -1 ? line.substr(0, line.find(' ')) : line;
- line = line.find(' ') != -1 ? line.substr(line.find(' ') + 1) : line;
- cout << "OVO ME ZANIMA" << tempString << " "<< line << endl;
- symbNew.id = id++;
- symbNew.name = tempElem;
- symbNew.sect_name = tempSection;
- symbNew.offset = sectionOffset; //mesto u sekciji
- symbNew.value = allOffset; //ukupno mesto u fajlu
- symbNew.type = tempSymbType;
- symbNew.pc_relative = '0';
- symbolTable.push_back(symbNew);
- tempSymbTable.push_back(symbNew);
- cout << tempElem;
- if (tempString == line) line = "";
- }
- // cout << "temp string starts " << tempString << " this is tempString" << endl;
- // cout << "prosao get" << endl;
- if (getInstructionMask(tempString) != "greska") {
- cout << "USLI SMO U DEO ZA INSTRUKCIJU" << getInstructionMask(tempString) << "\n";
- tempInstr = tempString;
- tempLineCode = getInstructionMask(tempString) + byteORword + "00";
- if (tempString == line) line = "";
- cout << "LINIJA ZA INSTRUKCIJU "<< tempLineCode << endl;
- } else {
- cout << "nije INSTRUKCIJa\n";
- if (tempInstr.empty()) {
- cout << "\n SKIP WORD BYTE ALIGN prvi put" << endl;
- if (getInstructionBytes(tempString) != -1 || tempString == ".align" ||
- tempString == ".skip") {
- // cout << "\n SKIP WORD BYTE ALIGN" << endl;
- //ako je skip ili align dodajemo toliko bajtova na izlazni kod
- if (tempString == ".align" || tempString == ".skip") {
- for (i = 0; i < stoi(line); i++) {
- tempLineCode += "00";
- }
- } else {
- cout << "word/byte" << endl;
- int isNum = isNumber(line);
- int isHex = isHexNumber(line);
- if (isNum == -1 && isHex == -1) {
- string tempValue = "UND";
- cout << "nekako nije br";
- for (i = 0; i < symbolTable.size(); i++) {
- if (symbolTable[i].name == line) {
- tempValue = symbolTable[i].value;
- break;
- }
- }
- if (tempValue != "UND") {
- int howManyBits = tempString == ".word" ? 16 : 8;
- tempLineCode += convertToBin(tempValue, howManyBits);
- cout << tempLineCode;
- } else {
- symbNew.id = id++;
- symbNew.name = line;
- symbNew.sect_name = "UND";
- symbNew.offset = 0; //mesto u sekciji
- symbNew.value = "-1";
- symbNew.type = tempSymbType;
- symbNew.pc_relative = '0';
- symbolTable.push_back(symbNew);
- cout << tempElem;
- if (tempElem == line) line = "";
- }
- } else {
- int howManyBits = tempString == ".word" ? 16 : 8;
- tempLineCode += convertToBin(line, howManyBits);
- cout << tempLineCode;
- }
- }
- line = "";
- } else {
- printf("Greska ne moze nista osim instrukcije posle labele");
- return 3;
- }
- }
- else {
- cout << "usli u else za operand";
- if(howManyOp == 0 && !tempString.empty()) {
- cout << "Ne moze da postoji operand!" << endl;
- return 4;
- }
- cout << "pre find operand" << tempString << endl;
- tempLineCode += findOperand(tempString);
- line = "";
- cout << "posle find operand";
- }
- }
- }
- }
- }
- allOffset += tempLineCode.length() / 8;
- sectionOffset += tempLineCode.length() / 8;
- // cout << "\n" << convertStringToHex(tempLineCode) << " a pravi string" << tempLineCode << endl;
- codeSecond += tempLineCode + " ";
- codeFirst += convertStringToHex(tempLineCode);
- tempSymbType = "local";
- tempLineCode = "";
- tempInstr = "";
- }
- for(i = 0; i < symbolTable.size(); i++) {
- cout << "\n simbol" << symbolTable[i].name << '\n';
- }
- for(i = 0; i < sectionTable.size(); i++) {
- cout << "\n sekcija" << sectionTable[i].name << '\n';
- }
- cout <<"ISPIS" << codeFirst << "\n all offset is " << allOffset;
- cout << codeSecond << "\n all offset is " << allOffset;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement