diff --git a/ia86.cpp b/ia86.cpp index f99fbed..499f0cc 100644 --- a/ia86.cpp +++ b/ia86.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -82,7 +83,7 @@ ScenarioWindow::ScenarioWindow (finalcut::FWidget* parent) : finalcut::FDialog{parent} { ((Menu*)this->getParent())->log.append("Chargement des scénarios"); - scenario=readscenario("./scenarios.txt"); + scenario=readscenario("./scenarios.json"); if (scenario.levels.size()==0) finalcut::FMessageBox::error(this, "Impossible de charger le scénario par défaut !"); listview.ignorePadding(); @@ -354,23 +355,59 @@ Assembler::Assembler(TextWindow *log) : log(log) code->assembled=false; } -MultiCode *Assembler::Createzone(std::string source) -{ - -} - MultiCode *Assembler::MultiAssemble(std::string source,uint32_t address) { - + MultiCode *mcode=new MultiCode; + std::istringstream stream(source); + std::string line; + std::regex regex("^ *.org 0x([0-F]+)$"); + Code *code=new Code; + bool begin=true; + int org=address; + code->address=org; + while (std::getline(stream, line)) + { + if (line.find(".org") != std::string::npos) + { + std::smatch match; + if(std::regex_search(line, match, regex)) + { + org=std::stoul(match.str(1), nullptr, 16); + } + if (!begin) + { + mcode->zones.push_back(*code); + code=new Code; + code->address=org; + } + } + else + { + code->src.append(line+"\n"); + } + begin=false; + } + if (code->src.size()>0) + mcode->zones.push_back(*code); + for(size_t i=0;izones.size();i++) + { + log->append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode->zones[i].address,8)+" -> "+to_string(mcode->zones[i].src.size())+" octets"); + log->append(mcode->zones[i].src); + mcode->zones[i].assembled=false; + mcode->zones[i].initialized=false; + this->Assemble(&mcode->zones[i]); + } + mcode->executed=false; + return mcode; } -Code *Assembler::Assemble(std::string source,uint32_t address) +void Assembler::Assemble(Code *code) { std::stringstream out; - size_t srcsize=source.size(); + size_t srcsize=code->src.size(); unsigned char src_char[srcsize+1]; - strcpy(reinterpret_cast(src_char), source.c_str()); - err2=ks_asm(ks, reinterpret_cast(src_char), address, &code->content, &code->size, &srcsize); + strcpy(reinterpret_cast(src_char), code->src.c_str()); + err2=ks_asm(ks, reinterpret_cast(src_char), code->address, &code->content, &code->size, &srcsize); if (err2 != KS_ERR_OK) { log->append("Erreur d'assemblage"); @@ -379,20 +416,17 @@ Code *Assembler::Assemble(std::string source,uint32_t address) } else { + out.clear(); out << "Assemblage réussi, taille du code :" << code->size; code->assembled=true; - log->append(out.str()); - /*out.str(""); - out.clear(); - if (codesize < 30) + if (code->size < 30) { - out << " "; - for (size_t count = 0; count < codesize; count++) - out << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (int)((uint8_t)code[count]) ; + out << "\n "; + for (size_t count = 0; count < code->size; count++) + out << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (int)((uint8_t)code->content[count]) ; log->append(out.str()); - }*/ + } } - return code; } //---------------------------------------------------------------------- @@ -985,8 +1019,7 @@ void Menu::end() void Menu::compile() { - code=asmer.Assemble(edit.get(),scenario.levels[scenar.getselected()].init.dump.regs.eip); - debug.set(unasmer.Desassemble(code)); + mcode=asmer.MultiAssemble(edit.get(),scenario.levels[scenar.getselected()].init.dump.regs.eip); } void Menu::about() diff --git a/ia86.h b/ia86.h index e2701cf..abfabdc 100644 --- a/ia86.h +++ b/ia86.h @@ -135,7 +135,7 @@ struct Code bool assembled; bool initialized; bool executed; - std::string code; + std::string src; }; struct MultiCode @@ -264,10 +264,9 @@ class Assembler { public: Assembler(TextWindow *log); - Code *Assemble(std::string source,uint32_t address); + void Assemble(Code *code); MultiCode *MultiAssemble(std::string source,uint32_t address); private: - MultiCode *Createzone(std::string source); ks_engine *ks; ks_err err; int err2; @@ -312,7 +311,8 @@ class Menu final : public finalcut::FDialog void loadLevel(); TextWindow log{this}; private: - Code *code = new Code(); + MultiCode *mcode = new MultiCode(); + Code *code=new Code(); void onTimer (finalcut::FTimerEvent*) override; void refresh(); void configureFileMenuItems(); diff --git a/scenarios.txt b/scenarios.json similarity index 55% rename from scenarios.txt rename to scenarios.json index 98a2054..f5a5241 100644 --- a/scenarios.txt +++ b/scenarios.json @@ -45,6 +45,47 @@ hlt", } - } + }, + { + "niveau_titre" : "Suite", + "niveau_description" : "Il faut connaitre...", + "niveau_tutoriel" : "Ceci vous...", + "niveau_code" : "mov ax,0x545 +inc dx +.org 0x9000 +pop db 'ceci est un test',0 +mov esi,0x44441234 + .org 0x3002 +hlt", + "niveau_droits" : 10, + "niveau_initial" : + { + "registres" : + { + "segments" : + { + }, + "généraux" : + { + "eax" : 0, + "ebx" : 0, + "ecx" : 0, + "edx" : 0, + "esi" : 0, + "edi" : 0, + "esp" : 0, + "ebp" : 0, + "eip" : 0 + }, + "drapeaux" : 1 + }, + "code" : "ceci est le code" + }, + "niveau_objectif" : + { + + + } + } ] }