2013-10-06 4 views
12

में एनओपी का बिंदु क्या है इसलिए मैंने निम्नलिखित कोड सी # में लिखा था।सीआईएल

class Test 
{ 
    int a; 
    System.IO.StreamReader reader; 

    public Test() 
    { 
     a = 5; 
     reader = new System.IO.StreamReader(String.Empty); 
    } 
} 

और आईएल में वर्ग के निर्माता इस

.method public hidebysig specialname rtspecialname 
     instance void .ctor() cil managed 
{ 
    // Code size  33 (0x21) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: call  instance void [mscorlib]System.Object::.ctor() 
    IL_0006: nop 
    IL_0007: nop 
    IL_0008: ldarg.0 
    IL_0009: ldc.i4.5 
    IL_000a: stfld  int32 Test2.Test::a 
    IL_000f: ldarg.0 
    IL_0010: ldsfld  string [mscorlib]System.String::Empty 
    IL_0015: newobj  instance void [mscorlib]System.IO.StreamReader::.ctor(string) 
    IL_001a: stfld  class [mscorlib]System.IO.StreamReader Test2.Test::reader 
    IL_001f: nop 
    IL_0020: ret 
} // end of method Test::.ctor 

तरह लग रहा है 3 nop आदेशों रहे हैं। (जो मुझे पता है कि कोई ऑपरेशन नहीं है)। उन आदेशों की क्या ज़रूरत है। मेरा मतलब है कि अगर nop

उत्तर

16

सी # कंपाइलर द्वारा उपयोग किया जाता है जब यह आपके प्रोग्राम के लिए .pdb फ़ाइल लिखता है। जिसमें डीबगिंग जानकारी है, जिसमें आपके कोड के लिए फ़ाइल + लाइन नंबर जानकारी शामिल है। डीबगर इसका उपयोग मशीन कोड को खोजने के लिए करता है जहां इसे ब्रेकपॉइंट सेट करते समय प्रोग्राम को निष्पादित करना बंद करने के लिए INT 3 निर्देश इंजेक्ट करने की आवश्यकता होती है। जिटर एमएसआईएल में प्रत्येक Opcodes.Nop के लिए एक एनओपी मशीन कोड निर्देश उत्सर्जित करता है।

जब आप public Test() पर ब्रेकपॉइंट सेट करते हैं तो पहला एनओपी उपयोग किया जाता है। ध्यान दें कि इसे के बाद बेस कंस्ट्रक्टर कॉल इंजेक्शन दिया गया है ताकि यह वैरिएबल ऑटो/लोकल/वॉच डिबगिंग विंडो में मान्य हो जाए।

दूसरी नॉप का उपयोग तब किया जाता है जब आप पहले {घुंघराले ब्रेस पर ब्रेकपॉइंट सेट करते हैं। वह रेखा बिल्कुल कोई कोड उत्पन्न नहीं करती है इसलिए नकली एमएसआईएल निर्देश की एक कठिन आवश्यकता है।

अंतिम} घुंघराले ब्रेस के लिए जेनरेट की गई तीसरी नॉप के लिए वही कहानी। जब आप उस पर ब्रेकपॉइंट सेट करते हैं तो आप विधि वापसी मूल्य (यदि कोई हो) का निरीक्षण कर सकते हैं। डीबग + विंडोज + रजिस्टर्स विंडो में परोक्ष रूप से दृश्यमान। वीएस2013 में सुधार हुआ।

तो यह सिर्फ आपके प्रोग्राम को डीबग करने में सहायता करता है, वे ब्रेकपॉइंट्स को अनुमानित रूप से कार्य करते हैं। जब आप अपने प्रोग्राम की रिलीज कॉन्फ़िगरेशन बनाते हैं तो उन एनओपी उत्पन्न नहीं होते हैं। एक बड़ा कारण है कि सी # प्रोजेक्ट में डीबग और रिलीज कॉन्फ़िगरेशन क्यों है। आप अभी भी रिलीज बिल्ड को डीबग कर सकते हैं, हालांकि यह एक बहुत ही उलझन वाला अनुभव है जो आपको अपनी सैनिटी पर संदेह करता है :)

3

के बजाय कोई आदेश नहीं था तो इसका अंतर क्या होगा, इन्हें डीबग मोड में निर्माण करते समय ब्रेकपॉइंट्स का समर्थन करने के लिए उपयोग किया जाता है और आपकी असेंबली के निष्पादन में कोई फर्क नहीं पड़ता।

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