Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Microsoft,derlenmiş ve bağlı kodu daha verimli bir şekilde yürütecek şekilde yeniden düzenlemek için kullandığı belirli tekniklere sahiptir. Bu teknikler, bellek hiyerarşileri için bileşeni iyileştirir ve eğitim senaryolarını temel alır.
Sonuçta elde edilen iyileştirme disk belleğini (ve sayfa hatalarını) azaltır ve kod ile veriler arasındaki uzamsal yerelliği artırır. Özgün kodun kötü konumlandırılmasıyla ortaya çıkan önemli performans sorunlarını giderir. Bu iyileştirmeden geçmiş bir bileşenin kodu veya veri bloğu bir işlev içinde ikilinin farklı konumlarına taşınmış olabilir.
Bu teknikler tarafından iyileştirilmiş modüllerde, kod ve veri bloklarının konumları genellikle normal derleme ve bağlama sonrasında bulundukları konumlardan farklı bellek adreslerinde bulunur. Ayrıca, en yaygın kullanılan kod yollarının aynı sayfalarda birbirine yakın bulunabilmesi için işlevler bitişik olmayan birçok bloka bölünmüş olabilir.
Bu nedenle, bir işlevin (veya herhangi bir simgenin) yanına bir kaydırma eklenmesi, optimize edilmemiş kodda sahip olacağı anlamıyla aynı olmayabilir.
Performance-Optimized Kodunda Hata Ayıklama
Hata ayıklarken, simgelerin yüklendiği herhangi bir modülde !lmi uzantı komutunu kullanarak bir modülün performans açısından iyileştirilmiş olup olmadığını görebilirsiniz:
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
Bu çıktıda , "Özellikler" satırında performans terimine dikkat edin. Bu, bu performans iyileştirmenin ntdll.dlluygulandığını gösterir.
Hata ayıklayıcı, uzaklık olmadan bir işlevi veya başka bir simgeyi anlayabilir; bu, işlevlerde veya diğer etiketlerde kesme noktalarını sorunsuz bir şekilde ayarlamanıza olanak tanır. Ancak, bir ayrıştırma işleminin çıkışı kafa karıştırıcı olabilir, çünkü bu ayrıştırma iyileştirici tarafından yapılan değişiklikleri yansıtır.
Hata ayıklayıcı özgün koda yakın kalmaya çalışacağından, bazı eğlenceli sonuçlar görebilirsiniz. Performans için iyileştirilmiş kodlarla çalışırken temel kural, iyileştirilmiş kod üzerinde güvenilir adres aritmetiği gerçekleştirememenizdir.
Aşağıda bir örnek verilmiştir:
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
Kesme noktası listesinden IPTransmit adresinin 0xF8640CA6 görebilirsiniz.
0xF864B4CB adresinde bu işlev içindeki bir kod bölümünü çözdüğünüzde, çıktı, bunun işlevin başlangıcından 0xE48 bayt sonrasında olduğunu gösterir. Ancak, işlevin tabanını bu adresten çıkarırsanız, gerçek uzaklık 0xA825 gibi görünür.
Olan şey şudur: Hata ayıklayıcı gerçekten de 0xF864B4CB'de başlayan ikili yönergelerin ayrıştırılması gösteriyor. Ancak hata ayıklayıcısı, uzaklığı basit çıkarma işlemiyle hesaplama yerine, iyileştirmeler gerçekleştirilmeden önce özgün kodda var olan işlev girdisine uzaklığı en iyi şekilde görüntüler. Bu değer 0xE48.
Öte yandan, IPTransmit+0xE48'a bakmaya çalışırsanız şunu görürsünüz:
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
Burada olan şey, hata ayıklayıcının IPTransmit sembolünü adres 0xF8640CA6 eşdeğeri olarak tanıması ve komut ayrıştırıcısının 0xF8640CA6 + 0xE48 = 0xF8641AEE bulmak için basit bir ekleme yapmasıdır. Bu adres daha sonra u (Unassemble) komutunun bağımsız değişkeni olarak kullanılır. Ancak bu konum çözümlendiğinde, hata ayıklayıcı bunun IPTransmit olmadığını ve 0xE48 uzaklığı olmadığını bulur. Aslında bu işlevin bir parçası değildir. Bunun yerine, ARPTransmit işlevine ve 0xD8 uzaklığına karşılık gelir.
Bunun nedeni, performans iyileştirmesinin adres aritmetiği aracılığıyla geri alınamaz olmasıdır. Hata ayıklayıcı, bir adres alıp özgün sembolünü ve ofsetini çıkarabilir, ancak bir sembol ve ofset alıp doğru adrese çevirmek için yeterli bilgiye sahip değildir. Sonuç olarak, sökme bu gibi durumlarda yararlı değildir.