├── 1.s ├── 10.s ├── 2.s ├── 3.s ├── 4.s ├── 5.s ├── 6.s ├── 7.s ├── 8.s ├── 9.s ├── Decompiler.cpp ├── Decompiler.pdf ├── README.md └── a.out /1.s: -------------------------------------------------------------------------------- 1 | mov r0, #0 2 | swi 0x6c 3 | mov r1, r0 @stores number of elements 4 | mov r2, #0 @stores sum 5 | mov r3, #0 @counter 6 | loop: 7 | mov r0, #0 8 | swi 0x6c 9 | ADD r2, r2, r0 10 | ADD r3, r3, #1 @counter increment 11 | CMP r3, r1 12 | BGE loop_exit 13 | B loop 14 | loop_exit: 15 | MOV r0, #1 16 | MOV r1, r2 17 | swi 0x6b 18 | swi 0x11 -------------------------------------------------------------------------------- /10.s: -------------------------------------------------------------------------------- 1 | B fact1 2 | fnstarts: 3 | loop: 4 | CMP r1,r0 @i <= N 5 | BGT exit 6 | MUL r2,r1,r2 7 | ADD r1,r1,#1 8 | B loop 9 | exit: 10 | MOV pc,lr 11 | fact1: 12 | MOV r0,#10 13 | MOV r2,#1 14 | MOV r1,#1 15 | BL fnstarts 16 | MOV r2,#3 17 | -------------------------------------------------------------------------------- /2.s: -------------------------------------------------------------------------------- 1 | mov r1,#0 2 | mov r3,#0 3 | loop: 4 | mov r2,#0 5 | loop2: 6 | add r3,r3,#1 7 | add r2,r2,#1 8 | cmp r2,#10 9 | blt loop2 10 | add r1,r1,#1 11 | cmp r1,#10 12 | blt loop 13 | mov r0, #1 14 | mov r1,r3 15 | swi 0x6b 16 | exit: 17 | 18 | 19 | -------------------------------------------------------------------------------- /3.s: -------------------------------------------------------------------------------- 1 | 2 | mov r0,#0 3 | swi 0x6c 4 | mov r1,r0 @ no of elements 5 | mov r2,#0 @counter 6 | mov r3,#1 @ stores fact 7 | loop: 8 | mov r0,#0 9 | swi 0x6c 10 | cmp r0,r1 11 | MUL r3,r0,r3 12 | 13 | add r2,r2,#1 14 | sub r1,r1,#1 15 | cmp r1,r2 16 | beq loop3 17 | 18 | cmp r1,#0 19 | beq loop_exit 20 | b loop 21 | 22 | loop1: 23 | add r3,r3,#1 24 | b loop 25 | loop3: 26 | add r3,r3,#2 27 | b loop 28 | loop_exit: 29 | MOV r0, #1 30 | MOV r1, r3 31 | swi 0x6b 32 | swi 0x11 33 | 34 | 35 | -------------------------------------------------------------------------------- /4.s: -------------------------------------------------------------------------------- 1 | b main 2 | fn: 3 | add r1,r1,#1 4 | cmp r1,#10 5 | bge skip 6 | mov r0,#0 7 | blx fn 8 | skip: 9 | mov pc,lr 10 | main: 11 | mov r0,#0 12 | swi 0x6c 13 | mov r1,r0 14 | blx fn 15 | mov r0,#1 16 | swi 0x6b 17 | -------------------------------------------------------------------------------- /5.s: -------------------------------------------------------------------------------- 1 | b main 2 | fib2: 3 | cmp r2, #5 4 | bne gr8 5 | mov pc, lr 6 | gr8: 7 | add r1,r1,r2 8 | add r2,r2,#1 9 | blx fib2 10 | mov pc, lr 11 | main: 12 | mov r1,#0 13 | mov r2,#1 14 | blx fib2 15 | mov r0, #1 16 | swi 0x6b 17 | swi 0x11 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /6.s: -------------------------------------------------------------------------------- 1 | MOV r7, #0 2 | MOV r0, #0 3 | SWI 0x6c 4 | MOV r6, r0 5 | MOV r1, #0 6 | MOV r2, #1 7 | CMP r6, #0 8 | BNE LOOP 9 | MOV r6, #20 10 | LOOP: 11 | ADD r1, r2, r1 12 | SUB r2, r1, r2 13 | MOV r0, #1 14 | SWI 0x6b 15 | MOV r0, #' ' 16 | SWI 0x0 17 | ADD r7, r7, #1 18 | CMP r7, r6 19 | BNE LOOP 20 | SWI 0x11 -------------------------------------------------------------------------------- /7.s: -------------------------------------------------------------------------------- 1 | mov r0, #0 2 | swi 0x6c 3 | mov r1, r0 @stores number of elements 4 | mov r2, #0 @stores sum 5 | mov r3, #0 @counter 6 | loop: 7 | mov r0, #0 8 | swi 0x6c 9 | ADD r2, r2, r0 10 | ADD r3, r3, #1 @counter increment 11 | CMP r3, r1 12 | BGE loop_exit 13 | B loop 14 | loop_exit: 15 | MOV r0, #1 16 | MOV r1, r2 17 | swi 0x6b 18 | swi 0x11 -------------------------------------------------------------------------------- /8.s: -------------------------------------------------------------------------------- 1 | mov r0, #0 2 | swi 0x6c 3 | MOV r2, r0 @r2 stores n 4 | MOV r3, #0 5 | MOV r4, #1 6 | MOV r6, #0 7 | MOV r7, #10 8 | MOV r8, #0 9 | loop: 10 | CMP r2, #1 11 | BLE loop_exit 12 | ADD r4, r4, r3 13 | SUB r3, r4, r3 14 | SUB r4, r4, r3 15 | ADD r4, r4, r3 16 | SUB r2, r2, #1 17 | CMP r2, #1 18 | B loop 19 | loop_exit: 20 | mov r4, r3 21 | loop1_5: 22 | CMP r4, #0 23 | BLE loop1_5exit 24 | mov r2, #0 @quotient 25 | mov r5, #0 @remainder 26 | loop2: 27 | SUB r4, r4, #10 28 | CMP r4, #0 29 | BLT loop2_exit 30 | ADD r2, r2, #1 31 | B loop2 32 | loop2_exit: 33 | add r5, r4, #10 34 | mul r8, r6, r7 35 | mov r6, r8 36 | add r6, r6, r5 37 | mov r4, r2 38 | 39 | B loop1_5 40 | loop1_5exit: 41 | mov r0, #1 42 | mov r1, r6 43 | swi 0x6b 44 | swi 0x11 45 | -------------------------------------------------------------------------------- /9.s: -------------------------------------------------------------------------------- 1 | MOV r1,#2 2 | MOV r2,#3 3 | MOV r3,#4 4 | ADD r0,r1,r2 @Add Q to R 5 | ADD r0,r0,r3 -------------------------------------------------------------------------------- /Decompiler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | typedef string (*FnPtr)(vector); 5 | typedef std::unordered_map command_map; 6 | 7 | const int varSize = 1000; 8 | 9 | class Function{ 10 | public: 11 | string F_name; 12 | vector > F_body; 13 | }; 14 | 15 | class Block{ 16 | public: 17 | int blockID; 18 | string Label; 19 | vector > instructions; 20 | vector breakPoint; 21 | vector incomingEdges; 22 | vector outgoingEdges; 23 | Block(int blockNo, vector > seqInstructions, string label, vector bP){ 24 | instructions = seqInstructions; 25 | blockID = blockNo; 26 | Label = label; 27 | breakPoint = bP; 28 | } 29 | int getFarthestIncomingEdge(){ 30 | if(incomingEdges.size()==0){ 31 | return -1; 32 | } 33 | return incomingEdges[incomingEdges.size()-1]; 34 | } 35 | void addIncomingEdge(int source){ 36 | incomingEdges.push_back(source); 37 | } 38 | void addOutgoingEdge(int destination){ 39 | outgoingEdges.push_back(destination); 40 | } 41 | }; 42 | 43 | class WhileLoop{ 44 | public: 45 | WhileLoop(int c){ 46 | startBlock = c; 47 | } 48 | int startBlock; 49 | vector continueConditions; 50 | vector continueJumps; 51 | vector breakConditions; 52 | vector breakJumps; 53 | }; 54 | 55 | class IfCondition{ 56 | public: 57 | int startBlock; 58 | int endBlock; 59 | string condition; 60 | IfCondition(int start, int end, string jump){ 61 | startBlock = start; 62 | endBlock = end; 63 | condition = jump; 64 | } 65 | }; 66 | 67 | class ControlTransferCommand{ 68 | public: 69 | int status=0; 70 | string condition; 71 | int block; 72 | string type; 73 | }; 74 | 75 | // Function prototypes 76 | void InitialiseCommands(command_map &listx); 77 | string removeComments(string); 78 | string removeblanklines(string); 79 | string addSpace(string); 80 | string removeTab(string); 81 | void preProcessFile(); 82 | void tokenizeProgram(); 83 | vector cleanUpTokens(vector); 84 | void writeTokensToFile(); 85 | void runConstructor(); 86 | void test(); 87 | string mulParser(vector); 88 | string movParser(vector); 89 | string subParser(vector); 90 | string cmpParser(vector); 91 | string swiIntegerIn(); 92 | string swiIntegerOut(); 93 | string swiCharacterOut(); 94 | string swiHandler(vector); 95 | string addParser(vector); 96 | string addsParser(vector); 97 | string subsParser(vector); 98 | string decompileSequentialInstruction(vector,command_map); 99 | void defineVariables(); 100 | vector sequentialTranslator(vector >, int); 101 | void dumpCode(vector, string, string); 102 | vector generateControlFlowModel(); 103 | void generateLinks(); 104 | WhileLoop detectWhileEndPoint(int); 105 | vector findWhileLoops(); 106 | vector findIfConditions(); 107 | void generateControlTransferCommands(); 108 | vector GenerateFunctionBody(); 109 | string loopTranslator(ControlTransferCommand); 110 | string addsParser(vector); 111 | string subsParser(vector); 112 | string blxParser(vector); 113 | string blParser(vector); 114 | void ClearGlobalStack(); 115 | void declarePrototype(); 116 | void detectFunctions(); 117 | bool checkIfNotWithinLoops(int); 118 | 119 | // Global Variables 120 | vector > Program; 121 | int variableCounter = 16; // Naming registers as "var"+to_string(variableCounter) 122 | map variableTable; // One to one mapping of registers and variables 123 | vector callFlowModel; 124 | map labelBlock; 125 | vector whileLoops; 126 | vector ifLoops; 127 | int breakJumpPoints[varSize]; 128 | ControlTransferCommand jumps[varSize]; 129 | int jumpClosing[varSize]; 130 | int ifEnding[varSize]; 131 | stack loopStack; 132 | vector FunctionArrayVector; 133 | vector > mainBody; 134 | vector returnSkipCount; 135 | map excludedIfs; 136 | map excludedWhiles; 137 | 138 | bool checkIfNotWithinLoops(int q){ 139 | for(int i=0;i=whileLoops[i].startBlock && q<=whileLoops[i].continueJumps[0]){ 145 | return false; 146 | } 147 | } 148 | for(int i=0;iifLoops[i].startBlock && q=whileLoops[i].startBlock && i<=whileLoops[i].continueJumps[0]){ 165 | excludedWhiles[i]=1; 166 | } 167 | } 168 | for(int i=0;iifLoops[i].startBlock && i functionNames; 201 | for(int i=0;i0){ 219 | if(Program[i][0].compare("mov")==0){ 220 | if(Program[i][1].compare("pc")==0){ 221 | returnSkipCount[fn]--; 222 | } 223 | } 224 | i++; 225 | } 226 | fn++; 227 | } 228 | while(i GenerateFunctionBody(){ 261 | vector body; 262 | for(int i=0;i sequentialInstructions = sequentialTranslator(callFlowModel[i].instructions, loopStack.size()); 264 | for(int j=0;j findIfConditions(){ 345 | vector temp; 346 | for(int i=0;i=i && breakJumpPoints[i]==0){ 349 | ifEnding[labelBlock[callFlowModel[i].breakPoint[1]]-1]++; 350 | IfCondition newIf(i, labelBlock[callFlowModel[i].breakPoint[1]]-1, callFlowModel[i].breakPoint[0]); 351 | temp.push_back(newIf); 352 | } 353 | } 354 | } 355 | return temp; 356 | } 357 | 358 | WhileLoop detectWhileEndPoint(int c){ 359 | Block b= callFlowModel[c]; 360 | WhileLoop temp(c); 361 | int i = b.incomingEdges.size()-1; 362 | while(b.incomingEdges[i]>=c){ 363 | temp.continueJumps.push_back(b.incomingEdges[i]); 364 | temp.continueConditions.push_back(callFlowModel[b.incomingEdges[i]].breakPoint[0]); 365 | i--; 366 | } 367 | int lastBlock = temp.continueJumps[0]; 368 | i = lastBlock; 369 | while(i>=c){ 370 | if(labelBlock[callFlowModel[i].breakPoint[1]] == lastBlock+2 && callFlowModel[lastBlock+1].instructions.size()==0){ 371 | temp.breakJumps.push_back(i); 372 | breakJumpPoints[i]=1; 373 | temp.breakConditions.push_back(callFlowModel[i].breakPoint[0]); 374 | } 375 | i--; 376 | } 377 | return temp; 378 | } 379 | 380 | vector findWhileLoops(){ 381 | vector temp; 382 | for(int i=0;i=i){ 385 | temp.push_back(detectWhileEndPoint(i)); 386 | } 387 | } 388 | } 389 | return temp; 390 | } 391 | 392 | string loopTranslator(ControlTransferCommand c) 393 | { 394 | string command=std::string(loopStack.size(),'\t'); 395 | if(c.type.compare("while")==0){ 396 | if(c.condition.compare("bgt")==0){ 397 | command+="} while(compareRegister > 0);"; 398 | } 399 | else if(c.condition.compare("ble")==0){ 400 | command+="} while(compareRegister <= 0);"; 401 | } 402 | else if(c.condition.compare("blt")==0){ 403 | command+="} while(compareRegister < 0);"; 404 | } 405 | else if(c.condition.compare("bge")==0){ 406 | command+="} while(compareRegister >= 0);"; 407 | } 408 | else if(c.condition.compare("bne")==0){ 409 | command+="} while(compareRegister != 0);"; 410 | } 411 | else if(c.condition.compare("beq")==0){ 412 | command+="} while(compareRegister == 0);"; 413 | } 414 | else if(c.condition.compare("b")==0){ 415 | command+="} while(1);"; 416 | } 417 | } 418 | else if(c.type.compare("continue")==0){ 419 | if(c.condition.compare("bgt")==0){ 420 | command+="if(compareRegister > 0){ \n\tcontinue; \n}"; 421 | } 422 | else if(c.condition.compare("ble")==0){ 423 | command+="if(compareRegister <= 0){ \n\tcontinue; \n}"; 424 | } 425 | else if(c.condition.compare("blt")==0){ 426 | command+="if(compareRegister < 0){ \n\tcontinue; \n}"; 427 | } 428 | else if(c.condition.compare("bge")==0){ 429 | command+="if(compareRegister >= 0){ \n\tcontinue; \n}"; 430 | } 431 | else if(c.condition.compare("bne")==0){ 432 | command+="if(compareRegister != 0){ \n\tcontinue; \n}"; 433 | } 434 | else if(c.condition.compare("beq")==0){ 435 | command+="if(compareRegister == 0){ \n\tcontinue; \n}"; 436 | } 437 | else if(c.condition.compare("b")==0){ 438 | command+="if(1){ \n\tcontinue; \n}"; 439 | } 440 | } 441 | else if(c.type.compare("break")==0){ 442 | if(c.condition.compare("bgt")==0){ 443 | command+="if(compareRegister > 0){ \n\tbreak; \n}"; 444 | } 445 | else if(c.condition.compare("ble")==0){ 446 | command+="if(compareRegister <= 0){ \n\tbreak; \n}"; 447 | } 448 | else if(c.condition.compare("blt")==0){ 449 | command+="if(compareRegister < 0){ \n\tbreak; \n}"; 450 | } 451 | else if(c.condition.compare("bge")==0){ 452 | command+="if(compareRegister >= 0){ \n\tbreak; \n}"; 453 | } 454 | else if(c.condition.compare("bne")==0){ 455 | command+="if(compareRegister != 0){ \n\tbreak; \n}"; 456 | } 457 | else if(c.condition.compare("beq")==0){ 458 | command+="if(compareRegister == 0){ \n\tbreak; \n}"; 459 | } 460 | else if(c.condition.compare("b")==0){ 461 | command+="if(1){ \n\tbreak; \n}"; 462 | } 463 | 464 | } 465 | else if(c.type.compare("if")==0){ // Inverted on purpose 466 | if(c.condition.compare("bgt")==0){ 467 | command+="if(compareRegister <= 0){"; 468 | } 469 | else if(c.condition.compare("ble")==0){ 470 | command+="if(compareRegister > 0){"; 471 | } 472 | else if(c.condition.compare("blt")==0){ 473 | command+="if(compareRegister >= 0){"; 474 | } 475 | else if(c.condition.compare("bge")==0){ 476 | command+="if(compareRegister < 0){"; 477 | } 478 | else if(c.condition.compare("bne")==0){ 479 | command+="if(compareRegister == 0){"; 480 | } 481 | else if(c.condition.compare("beq")==0){ 482 | command+="if(compareRegister != 0){"; 483 | } 484 | else if(c.condition.compare("b")==0){ 485 | command+="if(0){"; 486 | } 487 | } 488 | return command; 489 | 490 | } 491 | 492 | void generateLinks(){ 493 | int i=0; 494 | int blockID = 0; 495 | while(i generateCallFlowModel(){ 510 | ClearGlobalStack(); 511 | ControlTransferCommand main; 512 | loopStack.push(main); 513 | memset(jumpClosing,0,sizeof(jumpClosing)); 514 | memset(breakJumpPoints,0,sizeof(breakJumpPoints)); 515 | memset(ifEnding,0,sizeof(ifEnding)); 516 | int i=0; 517 | int blockID = 0; 518 | string currentLabel = ""; 519 | while(i > temp; 521 | while(i bP; 529 | if(i == Program.size() && (Program[i-1][0].at(0) == 'b') && (Program[i-1][0].compare("blx") != 0) && (Program[i-1][0].compare("bl") != 0)){ 530 | bP = Program[i-1]; 531 | } 532 | else if(i > temp; 550 | vector bp; 551 | bp.push_back("empty"); 552 | Block b(blockID, temp, currentLabel, bp); 553 | callFlowModel.push_back(b); 554 | generateLinks(); 555 | whileLoops = findWhileLoops(); 556 | ifLoops = findIfConditions(); 557 | generateControlTransferCommands(); 558 | vector body = GenerateFunctionBody(); 559 | return body; 560 | } 561 | 562 | vector sequentialTranslator(vector > pgm, int tabs){ 563 | command_map listx; 564 | InitialiseCommands(listx); 565 | vector temp; 566 | for(int i=0;i temp, string function, string signature){ 574 | ofstream fout; 575 | fout.open("output.c",ios::app); 576 | fout< splitCode; 580 | stringstream ss(code); 581 | string to; 582 | while(std::getline(ss,to,'\n')){ 583 | splitCode.push_back(to); 584 | } 585 | int j=0; 586 | string prefix = ""; 587 | while(splitCode[0].at(j)=='\t'){ 588 | prefix += '\t'; 589 | j++; 590 | } 591 | fout< instruction){ 606 | if(instruction[0].compare("swi")!=0){ 607 | cout<<"Cannot handle using swiHandler"<"<"<"<>s; 747 | s=s+".s"; 748 | 749 | fin.open(s); 750 | string line; 751 | string str; 752 | while(getline(fin,line)){ 753 | if(!line.empty()){ 754 | str+=line; 755 | str+='\n'; 756 | } 757 | } 758 | 759 | str=removeComments(str); 760 | str=removeTab(str); 761 | str=addSpace(str); 762 | 763 | 764 | // remove multiple spaces 765 | size_t pos; 766 | while( ( pos = str.find( " " ) )!=std::string::npos ) 767 | str = str.replace( pos, 2, " " ); 768 | 769 | // remove extra blank lines 770 | str=removeblanklines(str); 771 | 772 | ofstream fout; 773 | fout.open("output.c"); 774 | fout< cleanUpTokens(vector instruction){ 780 | for(int i=0;i=0;i--){ // Remove empty tokens 788 | if(instruction[i].empty()){ 789 | instruction.erase(instruction.begin()+i); 790 | } 791 | } 792 | if(instruction.size()==1){ // Marking labels 793 | if(instruction[0][instruction[0].length()-1]==':'){ 794 | string labelHeader = "$LABEL$"; 795 | instruction.insert(instruction.begin(),labelHeader); 796 | instruction[1].erase(remove(instruction[1].begin(), instruction[1].end(), ':'), instruction[1].end()); 797 | } 798 | } 799 | return instruction; 800 | } 801 | 802 | void writeTokensToFile(){ 803 | ofstream fout; 804 | fout.open("output.c"); 805 | for(int i=Program.size()-1;i>=0;i--){ 806 | if(Program[i].size()==0){ 807 | Program.erase(Program.begin()+i); 808 | } 809 | } 810 | for(int i=0;i begin(ss); 829 | istream_iterator end; 830 | vector splitLine(begin, end); // Splitting instruction by space 831 | splitLine = cleanUpTokens(splitLine); // cleaning up extra spaces, tabs, newlines and commas 832 | Program.push_back(splitLine); 833 | } 834 | writeTokensToFile(); 835 | } 836 | string mulParser(vector instruction){ 837 | if(instruction[0].compare("mul")!=0){ 838 | cout<<"Error in mulParser"< instruction){ 863 | if(instruction[0].compare("sub")!=0){ 864 | cout<<"Error in subParser"< instruction) 889 | { 890 | if(instruction[0].compare("cmp")!=0){ 891 | cout<<"Error in cmpParser"< instruction) 916 | { 917 | if(instruction[0].compare("mov")!=0){ 918 | cout<<"Error in movParser"<=4){ 933 | sourceTransform1 = "' '"; 934 | } 935 | else{ 936 | sourceTransform1 = sourceRegister1.substr(1); 937 | } 938 | } 939 | translatedCommand = targetTransform+" = "+sourceTransform1+";"; 940 | return translatedCommand; 941 | } 942 | 943 | string swiIntegerOut(){ 944 | string translatedCommand = ""; 945 | translatedCommand= "if(var1==1){ \n \tprintf(\"%d\",var2); \n} "; 946 | return translatedCommand; 947 | } 948 | 949 | string swiCharacterOut(){ 950 | string translatedCommand = "printf(\"%c\" ,var1); \n"; 951 | return translatedCommand; 952 | } 953 | 954 | string addParser(vector instruction){ 955 | if(instruction.at(0).compare("add")!=0){ 956 | cout<<"Error in addParser"< instruction){ 980 | if(instruction[0].compare("subs")!=0){ 981 | cout<<"Error in subsParser"< instruction){ 1005 | if(instruction.at(0).compare("adds")!=0){ 1006 | cout<<"Error in addsParser"< instruction){ 1030 | if(instruction.at(0).compare("blx")!=0){ 1031 | cout<<"Error in blxParser"< instruction){ 1039 | if(instruction.at(0).compare("bl")!=0){ 1040 | cout<<"Error in blParser"< instruction,command_map listx){ 1061 | return listx.at(instruction.at(0))(instruction); 1062 | } 1063 | void test(){ 1064 | 1065 | // MulParser Test 1066 | cout<<"mulParser() testing..."< temp; 1069 | temp.push_back("mul"); 1070 | temp.push_back("r2"); 1071 | temp.push_back("r2"); 1072 | temp.push_back("#11"); 1073 | cout<<"Output: "< temp1; 1081 | temp1.push_back("sub"); 1082 | temp1.push_back("r2"); 1083 | temp1.push_back("r2"); 1084 | temp1.push_back("#11"); 1085 | cout<<"Output: "< temp2; 1093 | temp2.push_back("cmp"); 1094 | temp2.push_back("r2"); 1095 | temp2.push_back("#11"); 1096 | cout<<"Output: "< temp3; 1104 | temp3.push_back("mov"); 1105 | temp3.push_back("r2"); 1106 | temp3.push_back("#11"); 1107 | cout<<"Output: "< temp4; 1115 | temp4.push_back("add"); 1116 | temp4.push_back("r2"); 1117 | temp4.push_back("r2"); 1118 | temp4.push_back("#11"); 1119 | cout<<"Output: "< temp5; 1127 | temp5.push_back("blx"); 1128 | temp5.push_back("loop"); 1129 | cout<<"Output: "<