2011-08-03 11 views
7

पुनर्प्राप्त करें मुझे सी # प्रोग्राम द्वारा वास्तविक x86 असेंबली आउटपुट देखने में दिलचस्पी है (सीएलआर बाइटकोड निर्देश नहीं)। क्या ऐसा करने का कोई अच्छा तरीका है?जेआईटी आउटपुट

उत्तर

4

आपको एसओएस/एसओएसईएक्स के साथ WinDbg का उपयोग करना चाहिए, यह सुनिश्चित करें कि जिस विधि को आप x86 कोड देखना चाहते हैं वह विधि तालिका में jitted है और फिर u कमांड के साथ वास्तविक unassembly देखें। इस प्रकार आप वास्तविक कोड देखेंगे।

जैसा कि अन्य लोगों ने यहां उल्लेख किया है, ngen के साथ आप कोड देख सकते हैं जो वास्तव में वास्तविक जेआईटी संकलन परिणाम से मेल नहीं खाता है। विजुअल स्टूडियो के साथ यह भी संभव है क्योंकि डीआईटी का संकलन इस तथ्य पर निर्भर करता है कि अगर डीबगर मौजूद है या नहीं।

यूपीडी: कुछ स्पष्टीकरण। WinDbg एक डीबगर भी है, लेकिन यह देशी एक है।

Here आप तकनीक को विस्तार से पढ़ सकते हैं।

7

विजुअल स्टूडियो में अपने एप्लिकेशन को डीबग करते समय, आप उस कोड पर राइट-क्लिक कर सकते हैं जहां आपने रोक दिया है (ब्रेकपॉइंट का उपयोग करके) और "Disassembly पर जाएं" पर क्लिक करें। आप मूल निर्देशों के माध्यम से डीबग कर सकते हैं।

डिस्क पर * .exe फ़ाइलों के साथ ऐसा करने के लिए, शायद आप देशी आउटपुट उत्पन्न करने के लिए NGen का उपयोग कर सकते हैं और फिर इसे अलग कर सकते हैं (हालांकि मैंने कभी कोशिश नहीं की है, इसलिए मैं गारंटी नहीं दे सकता कि यह काम करेगा)।

यहाँ साधारण अंकगणित आपरेशन से कुछ नमूना opcodes कि सी # में लिखा गया था इस प्रकार हैं:

 
      int x = 5; 
mov   dword ptr [ebp-40h],5 
      int y = 6; 
mov   dword ptr [ebp-44h],6 
      int z = x + y; 
mov   eax,dword ptr [ebp-40h] 
add   eax,dword ptr [ebp-44h] 
mov   dword ptr [ebp-48h],eax 
+0

ध्यान दें कि यदि आप वास्तविक अनुकूलित कोड देखना चाहते हैं तो आपको [यहां] (https://stackoverflow.com/a/4678883/238419) चरणों का पालन करना होगा –

2

आप एक ब्रेकपाइंट (Alt + Ctrl + डी रखने और फिर Dissassembly खिड़की देखने से विजुअल स्टूडियो डीबगर इस्तेमाल कर सकते हैं) या Native Image Generator Tool (ngen.exe) आज़माएं।

1

आप मेमोरी डंप कर सकते हैं। हालांकि, ध्यान दें कि इन-मेमोरी कोड में प्रत्येक विधि शामिल नहीं है।

ngen एओटी, या अगली बार कोड पीढ़ी करता है, जो कि जेआईटी कोड से अलग हो सकता है।

4

@IvanDanilov answered रूप में, आप WinDbg और एसओएस का उपयोग कर सकते हैं। मैं पैदल चलने के लिए अलग से जवाब दे रहा हूं।

using System; 

namespace TestArrayCompare 
{ 
    class Program 
    { 
     static bool AreEqual(byte[] a1, byte[] a2) 
     { 
      bool result = true; 
      for (int i = 0; i < a1.Length; ++i) 
      { 
       if (a1[i] != a2[i]) 
        result = false; 
      } 
      return result; 
     } 

     static void Main(string[] args) 
     { 
      byte[] a1 = new byte[100]; 
      byte[] a2 = new byte[100]; 
      if (AreEqual(a1, a2)) 
      { 
       Console.WriteLine("`a1' equals `a2'."); 
      } 
      else 
      { 
       Console.WriteLine("`a1' does not equal `a2'."); 
      } 
     } 
    } 
} 

कदम::

  1. ओपन WinDbg

    इस उदाहरण में, मैं से विधि AreEqual() के disassembly को देखना चाहते। फ़ाइल मेनू से, "निष्पादन योग्य खोलें ..." चुनें। EXE के स्थान पर ब्राउज़ करें (मेरे मामले में, C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release\TestArrayCompare.exe)।

  2. निर्देशिका प्रतीक पथ के लिए PDB फ़ाइल युक्त जोड़ें।उदाहरण के लिए:

     
    .sympath "C:\Users\Daniel\Documents\Visual Studio 2013\Projects\TestArrayCompare\TestArrayCompare\bin\Release" 
    
  3. WinDbg के कमान विंडो में, एक ब्रेकपाइंट सेट जब clr.dll के माध्यम से भरी हुई है: clr.dll पर g

  4. :

     
    sxe ld:clr 
    
  5. 'गो' आदेश चलाकर जारी रखें मॉडलोड, लोड एसओएस: .loadby sos clr

  6. उस विधि को तोड़ने के लिए बीपीएमडी चलाएं जिसके लिए आप वाई disassembly देखने के लिए sh। उदाहरण के लिए:

     
    0:000> !BPMD TestArrayCompare.exe TestArrayCompare.Program.AreEqual 
    Adding pending breakpoints... 
    
  7. 'गो' आदेश चलाकर फिर से जारी रखें: g

  8. भागो Name2EE विधि वर्णनकर्ता को देखने के लिए। उदाहरण के लिए:

     
    0:000> !Name2EE TestArrayCompare.exe TestArrayCompare.Program.AreEqual 
    Module:  00a62edc 
    Assembly: TestArrayCompare.exe 
    Token:  06000001 
    MethodDesc: 00a637a4 
    Name:  TestArrayCompare.Program.AreEqual(Byte[], Byte[]) 
    Not JITTED yet. Use !bpmd -md 00a637a4 to break on run. 
    
  9. "अभी तक JITTED नहीं" पंक्ति में BPMD आदेश चलाएं। उदाहरण के लिए:

     
    0:000> !bpmd -md 00a637a4 
    MethodDesc = 00a637a4 
    Adding pending breakpoints... 
    
  10. फिर से जारी रखें: g

  11. आप कमान विंडो में "JITTED ..." देखना चाहिए। जेआईटी कोड के पते को देखने के लिए Name2EE कमांड को दोबारा चलाएं। उदाहरण के लिए:

     
    0:000> !Name2EE TestArrayCompare.exe TestArrayCompare.Program.AreEqual 
    Module:  00a62edc 
    Assembly: TestArrayCompare.exe 
    Token:  06000001 
    MethodDesc: 00a637a4 
    Name:  TestArrayCompare.Program.AreEqual(Byte[], Byte[]) 
    JITTED Code Address: 00b500c8 
    
  12. डिसअसेंबल करने, सूचीबद्ध कोड पता पर शुरू u आदेश का उपयोग करें।

     
    0:000> u 00b500c8 L20 
    00b500c8 55    push ebp 
    00b500c9 8bec   mov  ebp,esp 
    00b500cb 57    push edi 
    00b500cc 56    push esi 
    ... 
    

(ऊपर के लिए, मैं WinDbg 6.3.9600.17200 X86 Windows 8.1 एसडीके से उपयोग कर रहा था।)

एक सरल संदर्भ SOS.dll (SOS Debugging Extension) reference page on MSDN है: उदाहरण के लिए।

संबंधित मुद्दे