|
Amikor az assembly nyelvet tanulva találkoztam a következő kódkal, egyszerűen azt hittem, hogy a program nem végződhet normálisan. Azonban a hibakeresés egylépéses követése után kiderült, hogy a program normálisan is véget érhet, és egy furcsa jelenség történt: amikor a program elkezdett futni a code:0005-ről code:0014-re, a jmp parancsgal tovább ugrott a code:0008-ra. Azonban amikor tovább lépünk előre, a program közvetlenül a code:0 (azaz a jelölő S1 szegmens) helyett a code:00 felé ugrik. Eleinte nem értettem, mi történik, de sok egylépéses megfigyelés után még mindig furcsán éreztem magam. Miután alaposan tanulmányoztam a JMP utasítások használatát a tankönyvben [1], majd a programot gépi kóddal kombinálva elemeztem, új megértést kaptam a JMP utasításokról. assemble kód cím eltolás (IP) gépi utasítások Tegyük fel CS:Code (egység: h) Kód szegmens 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 2. évad: JMP rövid S1 0020 EBF6 Nop 0022 90 Kód vége vége a kezdet 1. A következő két pontot világosan kell megérteni 1. A CPU utasítások végrehajtásának folyamata a következő: <1>. Olvassa el az utasítást a CS:IP által mutatott memóriaegységből, és helyezze be az utasításpufferbe. <2>. IP=IP+Az utasítás hossza, amelyet éppen a pufferbe olvasnak, vagyis az IP a következő utasításra mutat. <3>. Hajtsd végre a jelenlegi parancsot a pufferben. Menj a <1-es lépéshez> 2. A jmp rövid parancs jelentése a belső szegmens átvitelére <1>. IP az offset, vagyis az IP = jelölő címe – az első bájt címe a jmp parancs után. <2>. Ennek a parancsnak a feladata, hogy módosítsa az IP értékét, és a parancs végrehajtása után IP = IP + 8 bit eltolás < 3> és 8 bitek elmozdulási tartománya -128~127, és az eltolás komplement formájában fejezhető ki [2]. 2. Kódelemzés 1. 1. lépés: A program a belépési kezdettől kezd el futni (code:0005), amikor a code:0013~0014 utasítást végrehajtják, a jmp short S1 gépi kódja az S2 címkén átmásolódik code:0008-ra, és az IP 0016. Ekkor, feltételezve, hogy nincs jmp short s utasítás, a programot s2:jmp short s1 formátumra hajtják végre, jmp short s1 olvassák az utasításpufferbe és IP=0022; és az s2-ről s1-re történő átvitel a szegmensen belüli átvitel, a gépi kód formátuma EB disp, és disp=jelölés s1-jelölés s2=(00018-0022) komplement=F6, így a jmp short s1 parancs gépi kódjának EBF6-nak kell lennie. Ezért az EBF6 a kódba:0008~code:0009 egységbe kerül. 2. 2. lépés: Olvassa be a jmp short s (EBF0) utasítást az utasításpufferbe, IP=IP+0002=0018; az s-jelölés komplementkódja s0=(0008-0018) = F0, és az s0-ból s-be történő átvitel a szegmensen belüli átvitel, a gépi kód formátuma EB disp (azaz EBF0) 3. 3. lépés: a jmp short s(EBF0) parancs az IP módosítására szolgáló parancs, miután végrehajtotta az EBF0 parancsot, IP=IP+(jelölés s-jelölés s0)=0008, a kód:0008 egységre mutatva. 4. 4. lépés: Olvasd el az egységkód:0008 tartalmát. Mivel a jmp short s1 (EBF6) parancsot az s2-nél a kód:0008~code:0009 egységre másolják, az egység tartalmának olvasása után IP=IP+0002=000A 5. 5. lépés: A jmp rövid s1 (EBF6) utasítás az IP módosítására szolgáló parancs, miután végrehajtotta az EBF6 parancsot, IP=IP+(megjelölés s1-jelölés s2)=0000, a kód:0000 egységre mutatva. 6. 6. lépés: A program a code:0000 fájlra megy a végrehajtáshoz, vagyis a normál vég teljesül. 3. Utójel Elemezd helyesen ezt a kódot: Meg kell érteni a CPU utasításvégrehajtásának folyamatát és a jmp rövidítést? (IP-módosítással számítva). Ezen felül az eloszlási számítás eredményének komplementális kódja is kulcsfontosságú. Miután elemeztem ezt a látszólag szokatlan kódot, mélyebb megértést nyertem a JMP utasításairól az összeszerelésben.
|