|
Când am dat peste următorul cod în timp ce învățam limbajul de asamblare, am crezut pur și simplu că programul nu se poate termina normal. Totuși, după depanarea urmăririi single-step, s-a constatat că programul se putea încheia normal, iar un fenomen ciudat a apărut: când programul a început să ruleze de la cod:0005 la cod:0014, a continuat să sară la cod:0008 cu comanda jmp. Totuși, când continui să efectuezi un pas înainte, programul sare direct la code:0 în loc de code:0018 (adică la segmentul de desemnare S1). La început nu înțelegeam ce se întâmplă, dar după multe observații într-un singur pas, tot m-am simțit ciudat. După ce am studiat cu atenție utilizarea instrucțiunilor JMP din manual [1], și apoi am analizat programul în combinație cu codul mașină, am o nouă înțelegere a instrucțiunilor JMP. Instrucțiuni de mașină offset (IP) pentru adresa codului asamblat Să presupunem CS:Code (Unitate: H) Segment de cod 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: scurtmetraj jmp s1 0020 EBF6 NOP 0022 90 Sfârșitul codului Sfârșit de start 1. Următoarele două puncte trebuie înțelese clar 1. Procesul de execuție al instrucțiunilor CPU este următorul: <1>. Citește instrucțiunea din unitatea de memorie indicată de CS:IP și introduce-o în bufferul de instrucțiuni. <2>. IP=IP+Lungimea instrucțiunii care este citită în momentul de stoc în buffer, adică IP-ul indică următoarea instrucțiune. <3>. Execută comanda curentă în buffer. Mergi la pasul <1> 2. Semnificația comenzii scurte jmp pentru transferul segmentului intern <1>. IP este offset-ul, adică adresa la designatorul IP = - adresa primului octet după comanda jmp. <2>. Funcția acestei comenzi este de a modifica valoarea lui IP, iar după executarea comenzii, IP = IP + offset de 8 biți < biți 3> și 8 au un interval de deplasare de -128~127, iar decalajul este exprimat sub forma complementului [2]. 2. Analiza codului 1. Pasul 1: Programul începe să ruleze de la începutul intrării (cod:0005), când instrucțiunea cod:0013~0014 este executată, codul mașină al instrucțiunii jmp short S1 la eticheta S2 este copiat în cod:0008, iar IP-ul este 0016. În acest moment, presupunând că nu există o instrucțiune jmp short s, programul va fi executat în s2:jmp short s1, va citi jmp short s1 în bufferul de instrucțiuni și IP=0022; iar transferul de la s2 la s1 este transferul intra-segment, formatul codului mașină este EB disp, iar disp=designation s1-designation s2=(00018-0022) complement=F6, astfel încât codul mașină al comenzii jmp short s1 ar trebui să fie EBF6. Prin urmare, EBF6 este copiat în unitatea cod:0008~cod:0009. 2. Pasul 2: Citește scurta instrucțiune jmp s (EBF0) în buffer-ul de instrucțiuni, IP=IP+0002=0018; codul de complement al desemnării s s0=(0008-0018) = F0, iar transferul de la s0 la s este transferul intra-segment, iar formatul codului mașină este EB disp (adică EBF0) 3. Pasul 3: Comanda jmp short s(EBF0) este o comandă pentru a modifica IP-ul, după executarea comenzii EBF0, IP=IP+(desemnare s-desemnare s0)=0008, indicând către unitatea cod:0008. 4. Pasul 4: Citește conținutul codului unității:0008. Deoarece comanda jmp short s1 (EBF6) la s2 este copiată în unitatea cod:0008~cod:0009, după citirea conținutului unității, IP=IP+0002=000A 5. Pasul 5: Instrucțiunea jmp short s1 (EBF6) este o comandă de modificare a IP, după executarea comenzii EBF6, IP=IP+(desemnare s1-desemnare s2)=0000, indicând către codul:0000 unitate. 6. Pasul 6: Programul trece la cod:0000 pentru a se executa, adică sfârșitul normal este finalizat. 3. Postscriptum Analizați corect acest cod: Trebuie să înțelegeți procesul de execuție a instrucțiunilor CPU și jmp short? (calculat prin modificarea IP). În plus, codul de complement al rezultatului calculului decalajului este, de asemenea, o cheie. După ce am analizat acest cod aparent anormal, am dobândit o înțelegere mai profundă a instrucțiunilor JMP din asamblare.
|