|
Da jeg stødte på følgende kode, mens jeg lærte assemblersprog, tænkte jeg simpelthen, at programmet ikke kunne slutte normalt. Men efter debug single-step tracking blev det opdaget, at programmet kunne slutte normalt, og et mærkeligt fænomen opstod: da programmet begyndte at køre fra kode:0005 til kode:0014, fortsatte det med at hoppe til kode:0008 med kommandoen jmp. Men når man fortsætter med at udføre et skridt fremad, hopper programmet direkte til kode:0 i stedet for kode:0018 (dvs. betegnelsen S1-segmentet). I starten forstod jeg ikke, hvad der foregik, men efter mange observationer i ét trin følte jeg mig stadig mærkelig. Efter nøje at have studeret brugen af JMP-instruktioner i lærebogen [1], og derefter analyseret programmet i kombination med maskinkode, har jeg fået en ny forståelse af JMP-instruktioner. assemble code address offset (IP) maskininstruktioner Antag CS:kode (enhed: H) Kodesegment 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 short 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 Koden slutter slutstart 1. De følgende to punkter skal forstås klart 1. Processen for CPU-instruktionsudførelse er som følger: <1>. Læs instruktionen fra hukommelsesenheden, som CS:IP peger på, og læg den i instruktionsbufferen. <2>. IP=IP+Længden af den instruktion, der i øjeblikket læses ind i bufferen, det vil sige, IP'en peger på den næste instruktion. <3>. Udfør den aktuelle kommando i bufferen. Gå til trin <1> 2. Betydningen af jmp-kortkommandoen til at overføre det interne segment <1>. IP er offset, det vil sige adressen ved IP = designator – adressen på den første byte efter jmp-kommandoen. <2>. Funktionen af denne kommando er at ændre værdien af IP, og efter at have udført kommandoen, IP = IP + 8-bit offset < 3> og 8 bit har et forskydningsområde på -128~127, og offset udtrykkes som komplement [2]. 2. Kodeanalyse 1. Trin 1: Programmet begynder at køre fra indgangsstarten (kode:0005), når kode:0013~0014-sætningen udføres, bliver maskinkoden for sætningen jmp short S1 ved etiketten S2 kopieret til kode:0008, og IP-adressen er 0016. På dette tidspunkt, forudsat at der ikke findes nogen jmp short s-instruktion, vil programmet blive kørt til s2:jmp short s1, læse jmp short s1 ind i instruktionsbufferen og IP=0022; og overførslen fra s2 til s1 er intra-segment transfer, maskinkodeformatet er EB disp, og disp=betegnelse s1-betegnelse s2=(00018-0022) complement=F6, så maskinkoden for kommandoen jmp short s1 bør være EBF6. Derfor kopieres EBF6 til kode:0008~kode:0009-enheden. 2. Trin 2: Læs instruktionskortslutningen jmp s (EBF0) ind i instruktionsbufferen, IP=IP+0002=0018; komplementkoden for betegnelsen s0=(0008-0018) = F0, og overførslen fra s0 til s er intra-segmentoverførslen, og maskinkodeformatet er EB disp (dvs. EBF0) 3. Trin 3: Kommandoen jmp short s(EBF0) er en kommando til at ændre IP, efter at kommandoen EBF0 er udført, IP=IP+ (betegnelse s-betegnelse s0)=0008, hvilket peger på kode:0008-enheden. 4. Trin 4: Læs indholdet af enhedskode:0008. Da kommandoen jmp short s1 (EBF6) ved s2 kopieres til enheden: kode:0008~kode:0009, er indholdet af enheden læst, IP=IP+0002=000A 5. Trin 5: Instruktion jmp short s1 (EBF6) er en kommando til at ændre IP, efter at kommandoen EBF6 er udført, IP=IP+ (betegnelse s1-betegnelse s2)=0000, der peger på kode:0000-enheden. 6. Trin 6: Programmet går til kode:0000 for at udføre, det vil sige, at den normale afslutning er fuldført. 3. Efterskrift Analyser denne kode korrekt: Skal du forstå processen med CPU-instruktionsudførelse og JMP-kortslutning? (beregnet ved IP-ændring). Derudover er komplementkoden for offset-beregningsresultatet også en nøgle. Efter at have analyseret denne tilsyneladende unormale kode fik jeg en dybere forståelse af JMP-instruktionerne i assemblyen.
|