|
Kui ma assemblerkeelt õppides järgmise koodi peale sattusin, arvasin lihtsalt, et programm ei saa normaalselt lõppeda. Kuid pärast silumise üheastmelist jälgimist avastati, et programm võib lõppeda tavapäraselt, ning tekkis kummaline nähtus: kui programm hakkas täitma code:0005-st code:0014-ni, jätkas see jmp käsuga hüppamist code:0008-le. Kuid sammu edasi sooritamisel hüppab programm otse code:0 peale, mitte code:0018 (ehk tähise S1 segment). Alguses ma ei saanud aru, mis toimub, aga pärast mitmeid ühesammulisi tähelepanekuid tundsin end ikka imelikult. Pärast JMP käskude kasutamise hoolikat uurimist õpikus [1] ja seejärel programmi koos masinkoodiga analüüsimist sain uue arusaama JMP käskudest. assemble koodi aadressi nihke (IP) masinakäsud Oletame, et cs:code (ühik: h) Koodisegment MOV AX, 4C00H 0000 B8004C int 21h 0003 CD21 start: mov ax,0 0005 B80000 s: nop 0008 90 nop 0009 90 mov di, offset s 000A BF0800 Mov si, offset S2 000D BE2000 mov ax,cs:[si] CS:0020=F6EB mov cs:[di],ax CS:0008=9090 s0: jmp lühike s 0016 EBF0 s1: mov ax, 0 0018 B80000 int 21h 001B CD21 mov ax, 0 001D B80000 S2: JMP Short S1 0020 EBF6 nop 0022 90 kood lõpeb Lõpp algus 1. Järgmised kaks punkti tuleb selgelt mõista 1. CPU käskude täitmise protsess on järgmine: <1>. Loe käsk CS:IP poolt osutatud mäluühikust ja pane see käsupuhvri. <2>. IP=IP+Hetkel puhvrisse loetava käsu pikkus, see tähendab, et IP osutab järgmisele käsule. <3>. Täida puhveris praegune käsk. Mine sammule <1> 2. Jmp lühikäsu tähendus sisemise segmendi ülekandmiseks <1>. IP on nihe, see tähendab aadress IP = määraja juures – esimese baidi aadress pärast jmp käsku. <2>. Selle käsu funktsioon on muuta IP väärtust ning pärast käsu täitmist IP = IP + 8-bitine nihe < 3> ja 8 bitti nihkevahemik on -128~127 ning nihe väljendatakse täiendina [2]. 2. Koodianalüüs 1. Samm 1: Programm alustab käivitamist sisenemise algusest (kood:0005), kui code:0013~0014 lause käivitatakse, kopeeritakse väite jmp short S1 masinkood sildiga S2 aadressile code:0008 ja IP on 0016. Sel hetkel, eeldades, et jmp short s käsku ei ole, täidetakse programm s2:jmp short s1, loetakse jmp short s1 käsupuhvrisse ja IP=0022; ning ülekandmine s2-st s1-sse on segmendi ülekanne, masinkoodi formaat on EB disp ja disp=tähistus s1-tähistus s2=(00018-0022) complement=F6, seega peaks käsu jmp short s1 masinkood olema EBF6. Seetõttu kopeeritakse EBF6 koodi:0008~kood:0009 ühikule. 2. 2. samm: Loe käsk jmp short s (EBF0) käsupuhvrisse, IP=IP+0002=0018; tähistuse s-tähistuse täiendav kood s0=(0008-0018) = F0, ülekanne s0-st s-sse on segmendi ülekanne ning masinkoodi formaat on EB disp (st EBF0) 3. Samm 3: Käsk jmp short s(EBF0) on käsk IP muutmiseks pärast käsu EBF0 täitmist, IP=IP+(tähistus s-tähistus s0)=0008, osutades kood:0008 üksusele. 4. 4. samm: Loe ühiku koodi sisu: 0008. Kuna käsk jmp short s1 (EBF6) punktis s2 kopeeritakse üksusesse code:0008~code:0009, siis pärast ühiku sisu lugemist IP=IP+0002=000A 5. Samm 5: Käsk jmp short s1 (EBF6) on käsk IP muutmiseks pärast käsu EBF6, IP=IP+(tähistus s1-tähistus s2)=0000 täitmist, osutades koodile:0000 üksusele. 6. Samm 6: Programm läheb käivitamiseks code:0000 ehk tavapärane lõpp on täidetud. 3. Järelsõna Õigesti analüüsi seda koodi: Kas pead mõistma CPU käskude täitmise protsessi ja jmp lühist? (arvutatud IP modifikatsiooni alusel). Lisaks on võtmetähtsusega nihke arvutuse tulemuse komplementkood. Pärast selle näiliselt ebatavalise koodi analüüsimist sain sügavama arusaama JMP käskudest assembleris.
|