Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Microsoft memiliki teknik tertentu yang digunakannya untuk mengatur ulang kode yang dikompilasi dan ditautkan sehingga dijalankan dengan efisiensi yang lebih tinggi. Teknik ini mengoptimalkan komponen untuk hierarki memori, dan didasarkan pada skenario pelatihan.
Pengoptimalan yang dihasilkan mengurangi halaman (dan kesalahan halaman), dan meningkatkan lokalitas spasial antara kode dan data. Ini mengatasi hambatan performa utama yang disebabkan oleh posisi kode yang buruk. Komponen yang telah melalui pengoptimalan ini mungkin memiliki kode atau blok datanya dalam fungsi yang dipindahkan ke lokasi biner yang berbeda.
Dalam modul yang telah dioptimalkan oleh teknik ini, lokasi kode dan blok data akan sering ditemukan di alamat memori yang berbeda dari lokasi tempat mereka akan berada setelah kompilasi dan penautan normal. Selain itu, fungsi mungkin telah dibagi menjadi banyak blok yang tidak berdekatan, agar jalur kode yang paling umum digunakan dapat ditemukan dekat satu sama lain di halaman yang sama.
Oleh karena itu, fungsi (atau simbol apa pun) ditambah offset tidak akan selalu memiliki arti yang sama yang akan dimilikinya dalam kode yang tidak dioptimalkan.
Debugging kode Performance-Optimized
Saat penelusuran kesalahan, Anda dapat melihat apakah modul telah dioptimalkan performanya dengan menggunakan perintah ekstensi !lmi pada modul apa pun yang simbolnya telah dimuat:
0:000> !lmi ntdll
Loaded Module Info: [ntdll]
Module: ntdll
Base Address: 77f80000
Image Name: ntdll.dll
Machine Type: 332 (I386)
Time Stamp: 394193d2 Fri Jun 09 18:03:14 2000
CheckSum: 861b1
Characteristics: 230e stripped perf
Debug Data Dirs: Type Size VA Pointer
MISC 110, 0, 76c00 [Data not mapped]
Image Type: DBG - Image read successfully from symbol server.
c:\symbols\dll\ntdll.dbg
Symbol Type: DIA PDB - Symbols loaded successfully from symbol server.
c:\symbols\dll\ntdll.pdb
Dalam output ini, perhatikan istilah perf pada baris "Karakteristik". Ini menunjukkan bahwa pengoptimalan performa ini telah diterapkan ke ntdll.dll.
Debugger dapat memahami fungsi atau simbol lain tanpa offset; ini memungkinkan Anda untuk mengatur titik henti pada fungsi atau label lain tanpa masalah. Namun, output operasi pembongkaran mungkin membingungkan, karena pembongkaran ini akan mencerminkan perubahan yang dilakukan oleh pengoptimal.
Karena debugger akan mencoba untuk tetap dekat dengan kode asli, Anda mungkin melihat beberapa hasil yang lucu. Aturan praktis saat bekerja dengan kode yang telah dioptimalkan untuk performa adalah Anda tidak dapat melakukan perhitungan alamat yang dapat diandalkan pada kode yang dioptimalkan.
Berikut adalah contohnya:
kd> bl
0 e f8640ca6 0001 (0001) tcpip!IPTransmit
1 e f8672660 0001 (0001) tcpip!IPFragment
kd> u f864b4cb
tcpip!IPTransmit+e48:
f864b4cb f3a4 rep movsb
f864b4cd 8b75cc mov esi,[ebp-0x34]
f864b4d0 8b4d10 mov ecx,[ebp+0x10]
f864b4d3 8b7da4 mov edi,[ebp-0x5c]
f864b4d6 8bc6 mov eax,esi
f864b4d8 6a10 push 0x10
f864b4da 034114 add eax,[ecx+0x14]
f864b4dd 57 push edi
Anda dapat melihat dari daftar titik henti bahwa alamat IPTransmit adalah 0xF8640CA6.
Saat Anda menghapus seksi kode dalam fungsi ini pada 0xF864B4CB, output menunjukkan bahwa ini 0xE48 byte melewati awal fungsi. Namun, jika Anda mengurangi basis fungsi dari alamat ini, offset aktual tampaknya 0xA825.
Yang terjadi adalah: Debugger memang menunjukkan pembongkaran instruksi biner yang dimulai pada 0xF864B4CB. Tetapi alih-alih menghitung offset dengan pengurangan sederhana, debugger menampilkan -- sebaik mungkin -- offset ke entri fungsi seperti yang ada dalam kode asli sebelum pengoptimalan dilakukan. Nilai tersebut 0xE48.
Di sisi lain, jika Anda mencoba melihat IPTransmit+0xE48, Anda akan melihat ini:
kd> u tcpip!iptransmit+e48
tcpip!ARPTransmit+d8:
f8641aee 0856ff or [esi-0x1],dl
f8641af1 75fc jnz tcpip!ARPTransmit+0xd9 (f8641aef)
f8641af3 57 push edi
f8641af4 e828eeffff call tcpip!ARPSendData (f8640921)
f8641af9 5f pop edi
f8641afa 5e pop esi
f8641afb 5b pop ebx
f8641afc c9 leave
Apa yang terjadi di sini adalah bahwa debugger mengenali simbol IPTransmit setara dengan alamat 0xF8640CA6, dan pengurai perintah melakukan tambahan sederhana untuk menemukan bahwa 0xF8640CA6 + 0xE48 = 0xF8641AEE. Alamat ini kemudian digunakan sebagai argumen untuk perintah u (Unassemble). Tetapi setelah lokasi ini dianalisis, debugger menemukan bahwa ini bukan IPTransmit ditambah offset 0xE48. Memang, itu bukan bagian dari fungsi ini sama sekali. Sebaliknya, ini sesuai dengan fungsi ARPTransmit ditambah offset 0xD8.
Alasan ini terjadi adalah bahwa pengoptimalan performa tidak dapat dibalik melalui aritmatika alamat. Meskipun debugger dapat mengambil alamat dan menyimpulkan simbol serta offset aslinya, debugger tersebut tidak memiliki cukup informasi untuk mengambil simbol dan offset tersebut dan menerjemahkannya ke alamat yang benar. Akibatnya, pembongkaran tidak berguna dalam kasus ini.