|
Toen ik de volgende code tegenkwam tijdens het leren van assemblertaal, dacht ik simpelweg dat het programma niet normaal kon eindigen. Na debug single-step tracking bleek echter dat het programma normaal kon eindigen, en deed zich een vreemd fenomeen voor: wanneer het programma begon uit te voeren van code:0005 naar code:0014, bleef het met het jmp-commando naar code:0008 springen. Wanneer echter een stap vooruit wordt uitgevoerd, springt het programma direct naar code:0 in plaats van code:0018 (d.w.z. het segment van de aanduiding S1). In het begin begreep ik niet wat er aan de hand was, maar na vele observaties in één stap voelde ik me toch vreemd. Na zorgvuldig het gebruik van JMP-instructies in het leerboek [1] te hebben bestudeerd, en vervolgens het programma te hebben geanalyseerd in combinatie met machinecode, heb ik een nieuw begrip gekregen van JMP-instructies. assemble code address offset (IP) machine-instructies Ga uit van CS:Code (eenheid: H) Codesegment 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 21u 001B CD21 mov ax,0 001D B80000 s2: JMP short s1 0020 EBF6 NOP 0022 90 Code eindigt einde start 1. De volgende twee punten moeten duidelijk worden begrepen 1. Het proces van CPU-instructie-uitvoering verloopt als volgt: <1>. Lees de instructie van de geheugenunit waar CS:IP naar wijst en plaats deze in de instructiebuffer. <2>. IP=IP+De lengte van de instructie die momenteel in de buffer wordt gelezen, dat wil zeggen, het IP wijst naar de volgende instructie. <3>. Voer het huidige commando uit in de buffer. Ga naar stap <1> 2. De betekenis van het jmp short command om het interne segment over te zetten <1>. IP is de offset, dat wil zeggen, het adres op de IP = aanduiding - het adres van de eerste byte na het jmp-commando. <2>. De functie van dit commando is om de waarde van IP te wijzigen, en na het uitvoeren van het commando, IP = IP + 8-bits offset < 3> en 8 bits hebben een verplaatsingsbereik van -128~127, en de offset wordt uitgedrukt in de vorm van complement [2]. 2. Code-analyse 1. Stap 1: Het programma begint uit te voeren vanaf de ingangsstart (code:0005), wanneer de code:0013~0014-instructie wordt uitgevoerd, wordt de machinecode van de instructie jmp short S1 bij het label S2 gekopieerd naar code:0008, en het IP is 0016. Op dit moment, ervan uitgaande dat er geen instructie is voor korte s, wordt het programma uitgevoerd naar s2:jmp short s1, leest jmp short s1 in de instructiebuffer en IP=0022; en de overdracht van s2 naar s1 is de intra-segment overdracht, het machinecodeformaat is EB disp, en disp=aanduiding s1-aanduiding s2=(00018-0022) complement=F6, dus de machinecode van het commando jmp short s1 moet EBF6 zijn. Daarom wordt EBF6 gekopieerd naar de code:0008~code:0009-eenheid. 2. Stap 2: Lees de instructie jmp short s (EBF0) in de instructiebuffer, IP=IP+0002=0018; de complementcode van de aanduiding s-aanduiding s0=(0008-0018) = F0, en de overdracht van s0 naar s is de intra-segment overdracht, en het machinecodeformaat is EB disp (d.w.z. EBF0) 3. Stap 3: Het commando jmp short s(EBF0) is een commando om het IP te wijzigen, na het uitvoeren van het commando EBF0, IP=IP+(aanduiding s-aanduiding s0)=0008, verwijzend naar de code:0008-eenheid. 4. Stap 4: Lees de inhoud van eenheidscode:0008. Omdat het commando jmp short s1 (EBF6) op s2 wordt gekopieerd naar de code:0008~code:0009-eenheid, geldt na het lezen van de inhoud van de eenheid, IP=IP+0002=000A 5. Stap 5: Instructie jmp short s1 (EBF6) is een commando om IP te wijzigen, na het uitvoeren van het commando EBF6, IP=IP+ (aanduiding s1-aanduiding s2)=0000, verwijzend naar de code:0000-eenheid. 6. Stap 6: Het programma gaat naar code:0000 om uit te voeren, dat wil zeggen, het normale einde is voltooid. 3. Naschrift Correct analyseren van deze code: Moet je het proces van CPU-instructie-uitvoering en JMP short begrijpen? (berekend door IP-wijziging). Daarnaast is de complementcode van het offsetberekeningsresultaat ook een sleutel. Na het analyseren van deze schijnbaar abnormale code kreeg ik een dieper begrip van de JMP-instructies in de assembly.
|