2012-10-01 14 views
6

पर आधारित मैंने अभी आईएल को थोड़ा सा देखना शुरू कर दिया है और मैं उत्सुक हूं कि संकलक के आउटपुट से अतिरिक्त कोड को हटाने के लिए मेरा प्रयास (नीचे दिखाया गया) कोई अनपेक्षित दुष्प्रभाव था।हाथ से कोडित आईएल के बारे में प्रश्न अलग-अलग सरल सी # कोड

परिणामों के बारे में quesiton के एक जोड़े:

  1. मूल में nop संचालन के उद्देश्य क्या है?
  2. मूल में विधियों के अंत में br.s का उद्देश्य क्या है?
  3. क्या पुन: लिखित संस्करण किसी भी तरह से अनुचित है?

मूल सी # कोड:

class Program { 
    public static int Main() { 
     return Add(1, 2); 
    } 
    public static int Add(int a, int b) { 
     return a + b; 
    } 
} 

csc.exe साथ संकलित और ildasm.exe (मूल) के साथ यह disassembled:

.method public hidebysig static int32 Main() cil managed 
    { 
    .entrypoint 
    .maxstack 2 
    .locals init (int32 V_0) 
    IL_0000: nop 
    IL_0001: ldc.i4.1 
    IL_0002: ldc.i4.2 
    IL_0003: call  int32 Program::Add(int32, int32) 
    IL_0008: stloc.0 
    IL_0009: br.s  IL_000b 
    IL_000b: ldloc.0 
    IL_000c: ret 
    } 
    .method public hidebysig static int32 Add(int32 a, 
              int32 b) cil managed 
    { 
    .maxstack 2 
    .locals init (int32 V_0) 
    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: ldarg.1 
    IL_0003: add 
    IL_0004: stloc.0 
    IL_0005: br.s  IL_0007 
    IL_0007: ldloc.0 
    IL_0008: ret 
    } 

फिर से लिखा (समान उत्पादन का उत्पादन):

.method public hidebysig static int32 Main() cil managed 
    { 
    .entrypoint 
     .maxstack 2 
    ldc.i4.1 
    ldc.i4.2 
    call int32 Program::Add(int32, int32) 
    ret 
    } 

    .method public hidebysig static int32 Add(int32 a, int32 b) cil managed 
    { 
    .maxstack 2 
     ldarg.0 
     ldarg.1 
    add 
    ret 
    } 
+4

एनओपी "नो ऑपरेशन" वह जगह है जहां आप डिबगिंग के दौरान अपना ब्रेकपॉइंट सेट कर सकते हैं। इसे रिलीज के लिए संकलित करने का प्रयास करें। – Johnny

उत्तर

6

सभी 'अतिरिक्त' कोड आप देख डिबग करने के लिए विशिष्ट बनाता है (और आम तौर पर जारी करने के लिए दूर अनुकूलित हो जाता है बनाता है) और आप कुछ है कि आप आमतौर पर रिलीज निर्माण में ऐसा नहीं कर सकते प्रदर्शन करने के लिए अनुमति देता है।

डीबग बिल्ड कोड ऐसा है कि यह डीबग सत्र के दौरान ब्रेकपॉइंट्स सेट करने और स्टैक मानों को बदलने/जांचने में अधिकतम स्वतंत्रता की अनुमति देता है। इसके अलावा आईएल कोड को उच्च स्तर के कोड को जितना संभव हो सके नकल करना चाहिए ताकि प्रत्येक 'कारण' और 'प्रभाव' को उच्च स्तरीय कोड लाइनों में मैप किया जा सके।

अब अपने प्रश्नों के विशिष्ट होना:

मूल में nop संचालन के उद्देश्य क्या है?

एनओपी आपको उन स्थानों पर ब्रेकपॉइंट्स सेट करने की अनुमति देता है जिन्हें 'निष्पादित' नहीं किया जाता है। उदाहरण के लिए एक विधि, लूप या अगर कथन के उद्घाटन ब्रेसिज़। इन गैर-निष्पादन योग्य निर्देशों में से, उद्घाटन ब्रेस पर तोड़ने से आप ब्लॉक शुरू होने से ठीक पहले ढेर को संशोधित/जांच सकते हैं (हालांकि स्वीकार्य रूप से आप ब्रेस खोलने के बजाय ब्लॉक के निष्पादन की पहली पंक्ति को तोड़कर इसे आसानी से प्राप्त कर सकते हैं लेकिन यह अभी भी आपको उद्घाटन ब्रेस पर तोड़ने की आजादी देता है)

मूल में विधियों के अंत में br.s का उद्देश्य क्या है?

मूल कोड को देखते हुए, आपको अगली पंक्ति में स्वाभाविक रूप से 'गिरने' की अनुमति देने की बजाय अगली पंक्ति में 'कूद' के लिए बकवास होना पड़ सकता है। लेकिन इसे पढ़ने के रूप में:

"एक डीबग बिल्ड में, जब भी एक तरीका है, लौटने विधि के अंत के लिए कूद करने की जरूरत है, ढेर से वापसी मान पढ़ सकते हैं और उसके बाद मान"

तो क्या लाभ होता है यह डीबगिंग की पेशकश करता है?

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

क्या पुन: लिखित संस्करण किसी भी तरह से अनुचित है?

आपके कोड में कुछ भी अनुचित नहीं है। वास्तव में यदि आप रिलीज मोड में मूल बनाते हैं और उत्पन्न सीआईएल की जांच करते हैं, तो आप देखेंगे कि यह आपके जैसा ही है।

2

अस्वीकरण: मैं नहीं हूँ किसी भी माध्यम से एक आईएल विशेषज्ञ।

  1. एनओपी ऑपरेशन का उद्देश्य क्या है?

    कुछ समय पहले प्रोग्रामर.स्टैकएक्सएन्चेंज.com पर x86 एएसएम के मामले में इस बारे में एक बड़ी चर्चा हुई थी, यहां देखें: Purpose of NOP instruction and align statement in x86 assembly। यह अनिवार्य रूप से वही होगा।

  2. मूल में विधियों के अंत में br.s का उद्देश्य क्या है?

    यह विधि के अंत में सिर्फ एक शाखा है। यदि आपके पास इस फ़ंक्शन में एकाधिक रिटर्न पथ हैं तो इसे देखने के लिए और अधिक समझदारी होगी। जैसा कि यह खड़ा है, संकलक ने इसे अनुकूलित करने के बजाय इसे शामिल किया है (संभवतः एक कंपाइलर स्विच इसे अनुकूलित करेगा)।

  3. क्या पुन: लिखित संस्करण किसी भी तरह से अनुचित है?

    ऐसा नहीं है कि मैं देख सकता हूं। आपने अभी तक इतने सरल एप्लिकेशन के लिए आवश्यक संकलक के काम को बड़ा कर दिया है। यदि आप इस कोड में कोई और अतिरिक्त जोड़ना चाहते हैं तो अतिरिक्त आईएल को इसके कार्यों को पूरा करने की आवश्यकता होगी।

+0

मुझे लगता है कि आईएल में एनओपी वास्तव में दुर्भावनापूर्ण तरीके से इस्तेमाल नहीं किया जा सकता है जिस तरह से आप वर्णन के लिए जुड़े हुए हैं। आईएल के साथ, कंपाइलर जेआईटी को संकलित करने से पहले कोड को सत्यापित करता है और मेरा मानना ​​है कि कूदने का कोई तरीका नहीं है जो पते की एक श्रृंखला तक जा सकता है। – svick

+0

@svick जबकि यह सच है .. उस धागे पर अन्य जानकारी का धन है :) –

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