Kompiuterių architektūra

    Disasembleris

    Disasembleris - tai programa, daranti priešingą operaciją, negu asemblerio kompiliatorius: verčianti mašininį kodą į assemblerio kalbą. Pavyzdžiui, sukompiliavus komandą „MOV cl, bh“, gaunami du baitai „8A CF“. Taigi disasembleris perskaitęs du baitus, kurių reikšmės „8A CF“, turėtų išsiaiškinti, kad tai komanda MOV, kad naudojami baitiniai registrai cl ir bh, o priskyrimas vyksta į registrą cl. Reikėtų pažymėti, kad komandos gali būti tiek dviejų baitų (kaip pastarajame pavyzdyje), tiek vieno, trijų, keturių, penkių ar šešių baitų. Nustatyti, kokio ilgio bus kita komanda, galima tik tą komandą nuskaičius ir atpažinus. Pavyzdžiui, komandos „CMP [bx+0105], 0804“ mašininis kodas yra toks: „81 BF 05 01 04 08“. Perskaitęs pirmąjį baitą, „81“, disasembleris galės pasakyti tik tiek, kad tai yra komanda kuri turi betarpišką operandą, kuris yra dviejų baitų. Ir tik perskaitęs kitą baitą, „BF“, jis galės apskaičiuoti visą komandos dydį: 6 baitai (1 baitas („81“) + 1 baitas („BF“) + 2 baitai (poslinkis adreso formavimui) + 2 baitai (betarpiškas operandas)).
    Tiesa, norint atsiskaityti disasemblerį, nebūtina, kad jis mokėtų atpažinti visas Intel 8086 procesoriaus komandas, užteks pačių pagrindinių. Taip pat nebūtina „suprasti“ exe formato failų - užteks žymiai paprastesnio com formato.

    COM failai (arba kaip pritaikyti asemblerio kodą COM formatui)

    Programa com faile pasižymi tuo, kad ji naudoja tik vieną segmentą: duomenys, kodas, stekas yra saugomi vieno segmento adresų erdvėje ir registrų cs, ds, ss ir es reikšmės sutampa. Norint iš programos kodo gauti com failą, visų pirmą reikia duomenų segmentą perkelti į kodo segmentą, pavyzdžiui:

       .model small
       .code
    pirmas   DB   "Labas", 10, 13 "$"
    antras   DB   "Pranesimas$"
    ......
    pradzia:
       MOV   ah, 9
       MOV   dx, offset pirmas
       INT   21h
    ......
    END pradzia

    Tiesa, rekomenduočiau duomenų segmentą perkelti į pačią programos pabaigą (kaip parodyta pavyzdyje). Kodėl taip patogiau, bus paaiškinta vėliau.
    Kadangi atskiro steko segmento taip pat nebus, tai ir direktyvą „.stack“ taip pat reikia ištrinti.
    Kitas dalykas: pradžioje programos reikia įterpti direktyvą kompiliatoriui „ORG 100h“. Ši direktyva nurodo, kad programą reikia talpinti su poslinkiu 256 (= 100h) nuo bendrojo segmento pradžios. Pirmieji 256 baitai yra naudojami saugoti įvairią tarnybinę informaciją (pvz., komandinės eilutės parametrus).
    Visa kita yra daugiau sintaksiniai pakeitimai (kaip parodyta pavyzdyje).
    Norint gauti com failą, kodas (kuris yra asm faile) yra kompiliuojamas taip pačiai kaip ir norint gauti exe failą: „tasm programa“. Tačiau linkuojant reikia pridėti parametrą „/t“: „tlink /t programa“. Gautasis com failas yra komandų ir duomenų kratinys (rinkinys - jei gražiau skamba) ir nėra jokių galimybių atskirti, kuris baitas priklauso komandai ir turėtų būti disasembliuotas, o kuris baitas priklauso duomenims ir turėtų būti praleistas. Todėl normalu, kad disasembleris bandys į asemblerio kodą paversti net ir tai, kas tėra programos duomenys. Be to, jeigu duomenys yra programos pradžioj, normalu, kad disasembleris gali prašokti kodo pradžią. Tarkime, jei kodas prasideda komanda „MOV ah, 9“ arba mašininiu kodu „B4 09“, tai „B4“ gali būti priskirtas prieš tai buvusiai komandai, o nauja komanda pradedama dekompiliuoti nuo „09“. Tokiu atveju, pasiėmus dar vieną ar kelis baitus būtų gauta komanda OR tarp registro ir registro arba atminties. Taigi, kai duomenys yra kodo pradžioje, rezultatas gali „pavažiuoti“ ir gautis visai nepanašus į tai, kas turi gautis. Todėl testuojant patogiau, kai duomenys yra kodo pabaigoje ir po duomenų daugiau nėra jokių komandų.

    Reikalavimai disasembleriui:
  • Paleidus disasemblerį su argumentu "/?", jis turi išmesti aprašą: atsiskaitančiojo vardas, pavardė, kursas, grupė, trumpas programos aprašymas.
  • Visi parametrai disasembleriui turi būti paduodami komandine eilute, o ne prašant juos įvesti iš klaviatūros. Pvz.: disasm prog.com prog.asm.
  • Disasemblerio rezultatas turi būti išvedamas į failą.
  • Jeigu disasembleris paleistas be parametrų arba parametrai nekorektiški, reikia atspausdinti pagalbos pranešimą tokį patį, kaip paleidus disasemblerį su parametru "/?".
  • Disasembleris turi apdoroti įvedimo išvedimo (ir kitokias) klaidas. Pavyzdžiui, nustačius, kad nurodytas failas neegzistuoja - jis turi išvesti pagalbos pranešimą ir baigti darbą.
  • Failų skaitymo ar rašymo buferio dydis turi būti nemažesnis už 10 baitų.
  • Failo dydis gali viršyti skaitymo ar rašymo buferio dydį.
  • Su programa turi būti pateikiamas testinis com failas ir jo kodas asm faile.
  • Rezultatų faile turi būti išvedama poslinkis nuo kodo segmento pradžios, komandos mašininis kodas ir pati komanda. Turėkite omenyje, kad pirmoji komanda com faile yra su poslinkiu 100h nuo segmento pradžios.
  • Turi būti suprantamos ir disasembliuojamos šios komandos:
    • Segmento keitimo prefiksas;
    • Visi MOV variantai (6);
    • Visi PUSH variantai (3);
    • Visi POP variantai (3);
    • Visi ADD variantai (3);
    • Visi INC variantai (2);
    • Visi SUB variantai (3);
    • Visi DEC variantai (2);
    • Visi CMP variantai (3);
    • Komanda MUL;
    • Komanda DIV;
    • Visi CALL variantai (4);
    • Visi RET variantai (4);
    • Visi JMP variantai (5);
    • Visos sąlyginio valdymo perdavimo komandos (17);
    • Komanda LOOP;
    • Komanda INT;
    • Visi kitų komandų, kurios naudojamos testinėje programoje, variantai;
  • Jei nuskaičius baitą nesugebama jo atpažinti, reikia jį praleisti (apie tai pažymint rezultatų faile) ir bandyti atpažinti po jo einantį baitą;
    Pavyzdys:

    Pavyzdinė programa pvz0.asm. Pritaikyta com formatui programa pvz0com.asm. Ją sukompiliavus gautas com failas pvz0com.com. Galimo rezultatų failo pavyzdys rez.txt.