|
Ketika saya menemukan kode berikut saat belajar bahasa perakitan, saya hanya berpikir bahwa program tidak dapat berakhir secara normal. Namun, setelah debug pelacakan satu langkah, ditemukan bahwa program dapat berakhir secara normal, dan fenomena aneh terjadi: ketika program mulai dijalankan dari code:0005 ke code:0014, ia terus melompat ke code:0008 dengan perintah jmp. Namun, ketika terus melakukan langkah maju, program melompat langsung ke code:0 alih-alih code:0018 (yaitu, segmen S1 penunjuk). Awalnya, saya tidak mengerti apa yang sedang terjadi, tetapi setelah banyak pengamatan satu langkah, saya masih merasa aneh. Setelah mempelajari dengan cermat penggunaan instruksi JMP dalam buku teks [1], dan kemudian menganalisis program dalam kombinasi dengan kode mesin, saya memiliki pemahaman baru tentang instruksi JMP. Instruksi mesin Assemble Code Address Offset (IP) asumsikan cs:code (unit: h) segmen kode kapak mov, 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: kapak mov, 0 0018 B80000 int 21h 001B CD21 kapak mov, 0 001D B80000 s2: jmp short s1 0020 EBF6 NP 0022 90 kode berakhir Akhir Mulai 1. Dua poin berikut perlu dipahami dengan jelas 1. Proses eksekusi instruksi CPU adalah sebagai berikut: <1>. Baca instruksi dari unit memori yang ditunjuk oleh CS:IP dan masukkan ke dalam buffer instruksi. <2>. IP=IP+Panjang instruksi yang saat ini sedang dibaca ke dalam buffer, yaitu, IP menunjuk ke instruksi berikutnya. <3>. Jalankan perintah saat ini di buffer. Lanjutkan ke langkah <1> 2. Arti perintah singkat jmp untuk mentransfer segmen internal <1>. IP adalah offset, yaitu alamat di IP = penunjuk - alamat byte pertama setelah perintah jmp. <2>. Fungsi dari perintah ini adalah untuk memodifikasi nilai IP, dan setelah menjalankan perintah, IP = IP + 8 bit offset < bit 3> dan 8 memiliki rentang perpindahan -128~127, dan offset dinyatakan dalam bentuk komplemen [2]. 2. Analisis kode 1. Langkah 1: Program mulai dijalankan dari awal masuk (code:0005), ketika pernyataan code:0013~0014 dieksekusi, kode mesin dari pernyataan jmp short S1 pada label S2 disalin ke code:0008, dan IP-nya adalah 0016. Pada saat ini, dengan asumsi bahwa tidak ada instruksi jmp short s, program akan dijalankan ke s2:jmp short s1, baca jmp short s1 ke dalam buffer instruksi dan IP=0022; dan transfer dari s2 ke s1 adalah transfer intra-segmen, format kode mesin adalah EB disp, dan disp=designation s1-designation s2=(00018-0022) complement=F6, jadi kode mesin dari perintah jmp short s1 harus EBF6. Oleh karena itu, EBF6 disalin ke unit kode:0008~code:0009. 2. Langkah 2: Baca instruksi jmp short s (EBF0) ke dalam buffer instruksi, IP=IP+0002=0018; kode pelengkap penunjukan s-penunjukan s0=(0008-0018) = F0, dan transfer dari s0 ke s adalah transfer intra-segmen, dan format kode mesin adalah EB disp (yaitu, EBF0) 3. Langkah 3: Perintah jmp short s(EBF0) adalah perintah untuk memodifikasi IP, setelah menjalankan perintah EBF0, IP=IP+(penunjukan s-penunjukan s0)=0008, menunjuk ke unit code:0008. 4. Langkah 4: Baca isi kode satuan: 0008. Karena perintah jmp short s1 (EBF6) di s2 disalin ke code:0008~code:0009 unit, setelah membaca isi unit, IP=IP+0002=000A 5. Langkah 5: Instruksi jmp short s1 (EBF6) adalah perintah untuk memodifikasi IP, setelah menjalankan perintah EBF6, IP=IP+(penunjukan s1-designation s2)=0000, menunjuk ke code:0000 unit. 6. Langkah 6: Program pergi ke code:0000 untuk dieksekusi, yaitu, akhir normal selesai. 3. Catatan Akhir Analisis kode ini dengan benar: Perlu memahami proses eksekusi instruksi CPU dan jmp short? (dihitung dengan modifikasi IP). Selain itu, kode pelengkap dari hasil perhitungan offset juga menjadi kunci. Setelah menganalisis kode yang tampaknya tidak normal ini, saya mendapatkan pemahaman yang lebih dalam tentang instruksi JMP di perakitan.
|