záp. 8.2., 14:00

Vidlák
Matfyz(ák|ačka) level I
Příspěvky: 5
Registrován: 9. 6. 2005 12:00
Typ studia: Informatika Bc.
Bydliště: Vidlákov

záp. 8.2., 14:00

Příspěvek od Vidlák »

Tak tohle byl hodně tvrdej zápočet :(. Udělali to nakonec jenom 3 lidi, dvoum z nich to ani nefungovalo a dostaly to za to, že se blížili k výsledku.
Končilo se v 17:30 natvrdo, protože zkoušející musel jít domu hlídat děti :lol:. Kéž by důsledek toho(čas tři a půl hodiny včetně zadání) byl stejně vtipný.

zadání bylo následující:
implementovat simulátor na vykonavani assembler kódu. Implementace zahrnuje registr integerů, typovou paměť a hafo instrukcí.
Z příkazový řádky se načetl počet registrů, velikost paměti, typ paměti, soubor s kódem na vykonání, vstupní soubor, výstupní soubor.
Typy mohly být 3: I==int, F==float, C==třída(stačila třída racionálních čísel).
Instrukce:
ADDI I0=I1,I2 // sečte obsah registrů I1 a I2 a uloží do I0
SUBI I0=I1,I2 // odečte
MULI I0=I1,I2 // vynásobí
DIVI I0=I1,I2 // vydělí
SET0I I0 // registr I0 nastaví na 0
SET1I I0 // registr I0 nastaví na 1
CMP(X) I0=I1,I2 //výsledek porovnání se uloží do I0
- (X): EQ(==), NE(!=), L(<), LE(<=), G(>), GE(>=)
JNZ I0,R // (jump if not zero) když I0==0 tak GOTO R
JZ I0,R // (jump if zero) když I0!=0 tak GOTO R
READ I0 // ze vstupního souboru načte hodnotu do I0
WRITE I0 // vypíše I0 do výstupního souboru
MOV I0=I1 // zkopíruje hodnotu v I1 do I0
MOVM M0=M1 // zkopíruje paměť
LOAD M0=I1,I2 // M0=M[I1+I2]
STORE I0,I1=M2 // M[I1+I2]=M0
ADDM M0=M1,M2 // stejné jako aritmetika s obsahem paměti
SUBM M0=M1,M2
MULM M0=M1,M2
DIVM M0=M1,M2
READM M0 // načte do paměti M0 ze vstupního souboru
WRITEM M0 // vypíše obsah paměti M0 do výstupního souboru
CMPM(X) I0=M1,M2 // porovná obsah paměti M1 a M2 a výsledek uloží do I0(za (X) může být to samé, co v CMP)
EXIT N // skončí vykonávání kódu s návratovou hodnotou N

ještě bylo SETM1 a SETM0, ale ty byly nakonec zrušeny.

já to řešil tak, že simulator byl tahle třída:
template< class T> class simulator{
public:
T *_mem;
int *_reg;
simulator(){}
simulator(int IR, int M) { _reg= new int[IR]; _mem= new int[M];}
instrukce< T> _instr;
};
Kde IR bylo počet registrů a M velikost paměti.

instrukce implementovaný jako šablona:
template < class T>class instrukce{
public:
void mov(int &I1, int &I2){I1=I2;}
void add(int &I0, int &I1, int &I2){I0=I1+I2;}
void sub(int &I0, int &I1, int &I2){I0=I1-I2;}
void mul(int &I0, int &I1, int &I2){I0=I1*I2;}
void div(int &I0, int &I1, int &I2){I0=(int)(I1/I2);}
void cmpeq(int &I0, int &I1, int &I2){I1==I2 ? I0=1 : I0=0;}
void cmpne(int &I0, int &I1, int &I2){I1!=I2 ? I0=1 : I0=0;}
void cmpl(int &I0, int &I1, int &I2){I1<I2 ? I0=1 : I0=0;}
void cmple(int &I0, int &I1, int &I2){I1<=I2 ? I0=1 : I0=0;}
void cmpg(int &I0, int &I1, int &I2){I1>I2 ? I0=1 : I0=0;}
void cmpge(int &I0, int &I1, int &I2){I1>=I2 ? I0=1 : I0=0;}
void read(int &I0, fstream F){F >> I0;}
void write(int &I0, fstream F){F << I0;}
void movM(T &M0, T &M1){M0=M1;}
void load(T &M0, int &I1, int &I2, T *MP){M0=MP[I1+I2];}
void store(T &M0, int &I1, int &I2, T *MP){MP[I1+I2]= M0;}
void addm(T &M0, T &M1, T &M2){M0=M1+M2;}
void subm(T &M0, T &M1, T &M2){M0=M1-M2;}
void mulm(T &M0, T &M1, T &M2){M0=M1*M2;}
void divm(T &M0, T &M1, T &M2){M0=(T)(M1/M2);}
void readm(T &M0, fstream F){F >> M0;}
void writem(T &M0, fstream F){F << M0;}
void cmpmeq(int &I, T &M1, T &M2){M1==M2 ? I=1 : I=0;}
void cmpmne(int &I, T &M1, T &M2){M1!=M2 ? I=1 : I=0;}
void cmpml(int &I, T &M1, T &M2){M1<M2 ? I=1 : I=0;}
void cmpmle(int &I, T &M1, T &M2){M1<=M2 ? I=1 : I=0;}
void cmpmg(int &I, T &M1, T &M2){M1>M2 ? I=1 : I=0;}
void cmpmge(int &I, T &M1, T &M2){M1>=M2 ? I=1 : I=0;}
};

Ještě se musely napsat všemožný operátory pro třídu racionálních čísel(na porovnávání, aritmetiku a streamování)

Pak se v main podle typu ze vstupu jenom zadeklaroval simulator< typ> S. Kód sem si načet do vektoru po řádkách (odděleně jméno instrukce a parametry). Postupně by potom šlo volat příslušné funkce z S._instr. To sem ale už nedodělal. Chtěl sem to rozcaseovat podle názvů instrukcí, ale to mi nevzal. Snad to mělo být něco jako pole ukazatelů na funkce indexované jmény instrukcí.

Holt druhej pokus v háji.
Uživatelský avatar
jaruch
Supermatfyz(ák|ačka)
Příspěvky: 376
Registrován: 5. 2. 2005 14:06
Typ studia: Informatika Mgr.
Kontaktovat uživatele:

Příspěvek od jaruch »

akoze... ani som to zadanie necital... ale CO? Toto mam akoze spravit za tu trosku casu?
To bude dobry grc este, od zajtra musim kodit ako dabel, a aj tak sanca, ze to spravim, bude tak 5%...
Shit shit, who the fuck is shooting us?
I've got a universe to master...
Uživatelský avatar
Hugo
Donátor
Donátor
Příspěvky: 233
Registrován: 2. 6. 2005 13:31
Typ studia: Informatika Mgr.
Bydliště: treti kontejner zleva
Kontaktovat uživatele:

Příspěvek od Hugo »

jj, obzvlast nechutne zadani.

s tim 3h limitem bych rekl, ze urcite zatim jedno z nejtezsich. Za 4h bych to mozna dal, ale po 3h jsem to teprve zkompiloval..
Jinak jsem vubec nevyuzival sluzeb dedicnosti a rozrostlo se mi to na 1300 radku kodu, pricemz jsem zahy zjistil, ze priblize 500 je zbytecnych, ale i tak.. :)

No, snad priste budou nejake snadne manipulace s mapem a stringy..
Návštěvník

Příspěvek od Návštěvník »

Celková úspěšnost tohoto termínu byla 3/15. Z toho jen jeden člověk to stihnul napsat celé. Mě to nakonec uznal za to "blížení se" :wink:

Řešil jsem to trochu jinak. Nejprve tedy template třídu na paměť. registry jsou vlastně jen speciální případ, takže stačilo odvodit. To si čtenář doplní sám svým oblíbeným způsobem. V simulátoru si pak vytvořím ještě navíc vektor ukazatelů na abstraktní instrukci s jedinou virtuální metodou a každou jednotlivou si definuji jako potomka této třídy.

Kód: Vybrat vše

template< class T> class mem{
public:
   mem(int size): _pole(size) {};
   /* ... */
private:
   std::vector<T> _pole;
};

// registr obdobne nebo podedit

class Ainstr {
public:
  virtual void execute() = 0;
};

template< class T> class simulator{
public:
   simulator(int IR, int M): _reg(IR), _mem(M) {};
   void step() { _instr[_citac++]->execute(); };
   void loadsrc() { /* ... */ };
   /* ... */
private:
   int _citac;
   mem _mem;
   reg _reg;
   std::vector<Ainstr *> _instr;
};

class Iadd: public Ainstr {
public:
   virtual void execute() { /* ... */ };
private:
  int _p1,_p2,_p3; //vsechny potrebne parametry
};
Tohle je pochopitelně jen náznak řešení. Je v něm spousta chyb a chybí tam jakékoliv ošetření. Ani si nejsem jistý syntaktickou správností :wink: (Co byste chtěli takle pozdě...). Každopádně pak není problém instrukce přidávat, odebírat, upravovat,... Při načítání kódu pak stačí vytvářet instance těch konkrétních instrukcí. Myslím, že takle to bylo jednodušší na implementaci i na pozdější použití. Akorát vic psaní (copy & paste).

Ještě se hodí sdělení, že se vyplatilo používat výjimky.
Odpovědět

Zpět na „2005“