|
Kai mokydamasis asamblėjos kalbos susidūriau su šiuo kodu, tiesiog pagalvojau, kad programa negali baigtis normaliai. Tačiau po derinimo vieno žingsnio sekimo buvo nustatyta, kad programa gali baigtis normaliai, ir įvyko keistas reiškinys: kai programa pradėjo vykdyti nuo kodo:0005 iki kodo:0014, ji toliau peršoko į kodą:0008 su komanda jmp. Tačiau toliau atliekant žingsnį į priekį, programa pereina tiesiai į kodą:0, o ne kodą:0018 (t. y. žymeklio S1 segmentą). Iš pradžių nesupratau, kas vyksta, bet po daugelio vieno žingsnio stebėjimų vis tiek jaučiausi keistai. Atidžiai išstudijavęs JMP instrukcijų naudojimą vadovėlyje [1] ir išanalizavęs programą kartu su mašininiu kodu, turiu naują supratimą apie JMP instrukcijas. surinkti kodo adreso poslinkio (IP) mašinos instrukcijas Tarkime, CS:kodas (vienetas: h) Kodo segmentas MOV AX, 4C00H 0000 B8004C int 21h 0003 CD21 start: mov ax,0 0005 B80000 S: NOP 0008 90 Nr. 0009 90 mov di, poslinkis s 000A BF0800 mov si, ofsetas s2 000D BE2000 mov ax,cs:[si] CS:0020=F6EB mov cs:[di],ax CS:0008=9090 S0: JMP šortai S 0016 EBF0 S1: MOV AX,0 0018 B80000 int 21h 001B CD21 mov ax,0 001D B80000 S2: JMP trumpas S1 0020 EBF6 Nr. 0022 90 Kodas baigiasi Pabaigos pradžia 1. Reikia aiškiai suprasti šiuos du aspektus 1. CPU nurodymų vykdymo procesas yra toks: <1>. Perskaitykite instrukciją iš atminties bloko, kurį nurodė CS:IP, ir įdėkite ją į instrukcijų buferį. <2>. IP=IP+Instrukcijos, šiuo metu skaitomos į buferį, ilgis, tai yra, IP nurodo į kitą instrukciją. <3>. Vykdykite dabartinę komandą buferyje. Pereikite prie <1 veiksmo> 2. Trumposios komandos jmp reikšmė vidiniam segmentui perkelti <1>. IP yra poslinkis, tai yra adresas IP = žymeklis - pirmojo baito adresas po jmp komandos. <2>. Šios komandos funkcija yra pakeisti IP reikšmę, o įvykdžius komandą, IP = IP + 8 bitų poslinkis < 3> ir 8 bitų poslinkio diapazonas yra -128 ~ 127, o poslinkis išreiškiamas komplemento forma [2]. 2. Kodo analizė 1. 1 žingsnis: Programa pradedama vykdyti nuo įėjimo pradžios (kodas:0005), kai vykdomas kodas:0013~0014 sakinys, sakinio jmp trumpas S1 mašinos kodas etiketėje S2 nukopijuojamas į kodą:0008, o IP yra 0016. Šiuo metu, darant prielaidą, kad nėra jmp trumpos s instrukcijos, programa bus vykdoma į s2:jmp short s1, nuskaitys jmp short s1 į instrukcijų buferį ir IP=0022; o perkėlimas iš s2 į s1 yra vidinis perdavimas segmente, mašinos kodo formatas yra EB disp, o disp=designation s1-designation s2=(00018-0022) complement=F6, taigi komandos jmp short s1 mašinos kodas turėtų būti EBF6. Todėl EBF6 nukopijuojamas į kodą:0008~kodas:0009 vienetas. 2. 2 veiksmas: perskaitykite instrukciją jmp trumpas s (EBF0) į instrukcijų buferį, IP=IP+0002=0018; žymėjimo s papildymo kodas s0=(0008-0018) = F0, o perkėlimas iš s0 į s yra perkėlimas segmento viduje, o mašinos kodo formatas yra EB disp (t. y. EBF0) 3. 3 veiksmas: komanda jmp short s(EBF0) yra komanda modifikuoti IP, įvykdžius komandą EBF0, IP=IP+(žymėjimas s-žymėjimas s0)=0008, nurodant kodą:0008 vienetas. 4. 4 veiksmas: perskaitykite vieneto kodo turinį:0008. Kadangi komanda jmp trumpas s1 (EBF6) ties s2 nukopijuojama į kodą:0008~kodas:0009 vienetas, perskaičius įrenginio turinį, IP=IP+0002=000A 5. 5 žingsnis: Instrukcija jmp trumpas s1 (EBF6) yra komanda modifikuoti IP, įvykdžius komandą EBF6, IP=IP+(žymėjimas s1-žymėjimas s2)=0000, nurodant kodą:0000 vienetas. 6. 6 žingsnis: Programa eina į kodą:0000 vykdyti, tai yra, įprasta pabaiga baigta. 3. Postscriptas Teisingai išanalizuoti šį kodą: Reikia suprasti procesoriaus instrukcijų vykdymo procesą ir jmp trumpas? (apskaičiuota pagal TL pakeitimą). Be to, korespondentinio skaičiavimo rezultato papildymo kodas taip pat yra raktas. Išanalizavęs šį iš pažiūros nenormalų kodą, aš įgijau gilesnį supratimą apie JMP instrukcijas asamblėjoje.
|