diff --git a/decompiled.txt b/decompiled.txt new file mode 100644 index 0000000..633d1b7 --- /dev/null +++ b/decompiled.txt @@ -0,0 +1,10 @@ +NOP +NOP +PUSH 4 +LD 72 +LD 60 +MUL +SUB +ST 144 +STL 4 +STL 0 diff --git a/decompiler.cpp b/decompiler.cpp new file mode 100644 index 0000000..848532b --- /dev/null +++ b/decompiler.cpp @@ -0,0 +1,59 @@ +#include "decompiler.h" +#include +#include +#include +#include "parser.h" + +#define SIMPLE(X) f << X << std::endl; pos++; break +// [RZC 05/05/2021] To solve alignment problems on ARM architectures we have to first copy the 4 bytes to an aligned byte array, then cast it to float +#define FVAR(X) memcpy(data, &code[pos+1], 4); f << X << " " << *((float*)data) << std::endl; pos += 5; break +#define IVAR(X) memcpy(data, &code[pos+1], 4); f << X << " " << *((uint32_t*)data) << std::endl; pos += 5; break + +void decompiler_save(const uint8_t *code, const int size) { + uint8_t data[4]; + int pos = 0; + float fval = 0; + uint32_t ival = 0; + std::ofstream f("decompiled.txt"); + if (f.is_open()) { + while (pos < size) { + switch (code[pos]) { + case OP_NOP: SIMPLE("NOP"); + case OP_PUSH: FVAR("PUSH"); + case OP_POP: SIMPLE("POP"); + case OP_DUP: SIMPLE("DUP"); + case OP_SWAP: SIMPLE("SWAP"); + case OP_LD: IVAR("LD"); + case OP_ST: IVAR("ST"); + case OP_LDL: IVAR("LDL"); + case OP_STL: IVAR("STL"); + case OP_JMP: IVAR("JMP"); + case OP_JNT: IVAR("JNT"); + case OP_JTR: IVAR("JTR"); + case OP_RET: SIMPLE("RET"); + case OP_CALL: IVAR("CALL"); + case OP_CALLEX: IVAR("CALLEX"); + case OP_ADD: SIMPLE("ADD"); + case OP_SUB: SIMPLE("SUB"); + case OP_MUL: SIMPLE("MUL"); + case OP_DIV: SIMPLE("DIV"); + case OP_MOD: SIMPLE("MOD"); + case OP_AND: SIMPLE("AND"); + case OP_OR: SIMPLE("OR"); + case OP_NOT: SIMPLE("NOT"); + case OP_NEG: SIMPLE("NEG"); + case OP_INC: SIMPLE("INC"); + case OP_DEC: SIMPLE("DEC"); + case OP_CONCAT: SIMPLE("CONCAT"); + case OP_EQ: SIMPLE("EQ"); + case OP_NEQ: SIMPLE("NEQ"); + case OP_LT: SIMPLE("LT"); + case OP_GT: SIMPLE("GT"); + case OP_LEQ: SIMPLE("LEQ"); + case OP_GEQ: SIMPLE("GEQ"); + case OP_SLEEP: SIMPLE("SLEEP"); + } + } + f.close(); + } +} diff --git a/decompiler.h b/decompiler.h new file mode 100644 index 0000000..6ab141f --- /dev/null +++ b/decompiler.h @@ -0,0 +1,4 @@ +#pragma once +#include + +void decompiler_save(const uint8_t *code, const int size); diff --git a/parser.cpp b/parser.cpp index 4f18547..99083b0 100644 --- a/parser.cpp +++ b/parser.cpp @@ -9,6 +9,7 @@ #include #include #include +#include "decompiler.h" #define MAX_CODE_SIZE 65536 #define MAX_LABELS 256 @@ -326,7 +327,7 @@ static void parse_expr_atom() { const int address = get_variable_address(); if (address == -1) return; emmit(scope_is_local() ? OP_LDL : OP_LD); - emmit(address); + emmit_dw(address); tkn_next(); return; } else { @@ -890,7 +891,9 @@ void parser_parse(const char* buffer, byte* mem) { //codepos = 0xA000; //emmit(OP_JMP); //emmit_w(0xA000); - } + } else { + decompiler_save(code, codepos); + } //FILE *f = fopen("test.bin", "wb"); //fwrite(mem, codepos, 1, f); diff --git a/scope.cpp b/scope.cpp index c529a13..c422734 100644 --- a/scope.cpp +++ b/scope.cpp @@ -65,7 +65,7 @@ const int scope_declare_variable(const std::string name, const uint32_t type, co const uint32_t address = scope.total_size; const t_variable var {name, type, length, address}; scope.variables.push_back(var); - scope.total_size += types_get_length(type) + (length == 0 ? 1 : length); + scope.total_size += types_get_length(type) * (length == 0 ? 1 : length); return address; } diff --git a/types.cpp b/types.cpp index 8dc7afe..66214e8 100644 --- a/types.cpp +++ b/types.cpp @@ -37,7 +37,7 @@ const int types_add_member(const uint32_t type, const std::string name, const ui for (auto m : types[type].members) if (m.name == name) return -1; const t_variable new_var {name, var_type, length, types[type].size}; types[type].members.push_back(new_var); - types[type].size += types_get_length(var_type) + length; + types[type].size += types_get_length(var_type) * length; return types[type].members.size()-1; }