2009-05-18 10 views
5

क्या कोई एमएसआईएल की इन कुछ पंक्तियों को समझा सकता है? यह स्थानीय चर में मूल्यांकन स्टैक से मूल्य को क्यों स्थानांतरित करता है, केवल इसे तुरंत वापस ले जाने और इसे वापस करने के लिए?क्या कोई एमएसआईएल की इन कुछ पंक्तियों को समझा सकता है?

निम्नलिखित एमएसआईएल कोड एक एकल तर्क (एक स्ट्रिंग) लोड करता है, एक विधि को कॉल करता है, जो बूल देता है, और उसके बाद उस बूल मान देता है। जो मुझे समझ में नहीं आता है, वह स्थानीय चर में विधि के रिटर्न वैल्यू को स्टोर करने के लिए stloc.0 कहता है, फिर अगली लेबल वाली लाइन (अनावश्यक लगता है) में एक स्पष्ट बिना शर्त नियंत्रण स्थानांतरण करता है, केवल मूल्य को वापस ले जाने के लिए इसे वापस करने से पहले मूल्यांकन ढेर।

.maxstack 1 
.locals init ([0] bool CS$1$0000) 
L_0000: nop 
L_0001: ldarg.0 
L_0002: call bool FuncNameNotImporant::MethodNameNotImporant(string) 
L_0007: stloc.0 
L_0008: br.s L_000a 
L_000a: ldloc.0 
L_000b: ret 

कारण है कि यह इस मूल्यांकन स्टैक पर मूल्य सुनिश्चित करने के लिए प्रकार की जांच किसी तरह का प्रदर्शन करने के लिए है है पर मेरे सर्वोत्तम अनुमान वास्तव में यह लौटने से पहले एक बूलियन मान है। लेकिन मैं अगली पंक्ति में स्पष्ट कूद के बारे में अनजान हूं; मेरा मतलब है, वैसे भी यह वहाँ नहीं होगा? विधि के लिए सी # स्रोत कोड केवल एक पंक्ति है, जो विधि का परिणाम देता है।

उत्तर

7

आप डिबग मोड में संकलित कोड के साथ डीबगर में इस समारोह को खोलते हैं,:

bool foo(string arg) 
{ 
    return bar(arg); 
} 

3 ब्रेक अंक आप सेट कर सकते हैं कर रहे हैं:

  1. समारोह के उद्घाटन ब्रेस पर।
  2. "वापसी" लाइन पर।
  3. फ़ंक्शन की समाप्ति ब्रेस पर।

उद्घाटन ब्रेस पर ब्रेक पॉइंट सेट करना मतलब है "इस समारोह को कॉल करने के दौरान तोड़ें"। यही कारण है कि विधि की शुरुआत में नो-ऑप निर्देश है। जब ब्रेकपॉइंट उद्घाटन ब्रेस पर सेट होता है तो डीबगर वास्तव में इसे नो-ऑप पर सेट करता है।

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

$retTmp = retVal; 
goto exit; 

में

return retVal; 

परिवर्तित करने के लिए और फिर इंजेक्शन लगाने के लिए निम्न कोड द्वारा:

exit: 
return $ret; 

इसके अलावा, जब डीबग मोड में, कंपाइलर्स वे पीढ़ी के कोड के बारे में बेवकूफ हैं।वे मूल रूप से की तरह कुछ कार्य करें:

GenerateProlog(); 
foreach (var statement in statements) 
{ 
    Generate(statement); 
} 
GenerateEpilog(); 

आपके मामले में, आप देख रहे हैं:

return foo(arg); 

में अनुवाद किया जा रहा है:

; //this is a no-op 
bool retTemp = false; 
retTemp = foo(arg); 
goto exit; 
exit: 
return retTemp; 

तो संकलक एक "रपट खिड़की अनुकूलन" कर रहा था यह उस कोड को देखने में सक्षम हो सकता है और महसूस हो सकता है कि कुछ अनावश्यकता थी। हालांकि, कंपाइलर्स आमतौर पर डीबग मोड में ऐसा नहीं करते हैं। कंपाइलर ऑप्टिमाइज़ेशन वैरिएबल को खत्म करने जैसी चीजें कर सकते हैं, और निर्देशों को पुन: व्यवस्थित कर सकते हैं, जो डिबगिंग को मुश्किल बनाते हैं। चूंकि डीबग बिल्डिंग का उद्देश्य डीबगिंग को सक्षम करना है, इसलिए ऑप्टिमाइज़ेशन चालू करना अच्छा नहीं होगा।

रिलीज निर्माण में, कोड ऐसा दिखाई नहीं देगा। यही कारण है कि बहुत सरल लग रही समाप्त होता है

return bar(arg); 

: ऐसा इसलिए है क्योंकि संकलक खोलने और बंद करने ब्रेसिज़, जो सिर्फ निम्नलिखित पत्ते पर breakpoints सक्षम करने के लिए विशेष कोड संकलित की परिचय नहीं करता है।

ध्यान देने योग्य एक बात यह है कि मुझे नहीं लगता कि सी # कंपाइलर खुदरा निर्माण में भी बहुत अधिक स्लाइडिंग विंडो अनुकूलन करता है। Thats क्योंकि उनमें से अधिकतर अनुकूलन अंतर्निहित प्रोसेसर आर्किटेक्चर पर निर्भर करते हैं और इसलिए जेआईटी कंपाइलर द्वारा किया जाता है। ऑप्टिमाइज़ेशन करना, सी # कंपाइलर में प्रोसेसर अज्ञेयवादी भी कोड को अनुकूलित करने की जेआईटी की क्षमता को बाधित कर सकते हैं (यह गैर-अनुकूलित कोड पीढ़ी द्वारा उत्पन्न पैटर्न की तलाश में है, और यदि यह अत्यधिक अनुकूल आईएल देखता है तो यह प्राप्त हो सकता है उलझन में)। तो आमतौर पर मैंग किए गए कोड कंपाइलर्स उन्हें नहीं करते हैं। यह कुछ "महंगे चीजें" (जो कि जेआईटी रनटाइम पर नहीं करना चाहता), जैसे मृत कोड पहचान, और लाइव चर विश्लेषण, लेकिन वे खिड़की अनुकूलन स्लाइडिंग द्वारा हल की गई समस्याओं का समाधान नहीं करते हैं।

4

क्या आप डीबग या रिलीज मोड में संकलित कर रहे हैं? रिलीज मोड में मुझे मिलता है:

.method private hidebysig static bool Test1(string arg) cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.0 
    L_0001: call bool FuncNameNotImportant::MethodNameNotImportant(string) 
    L_0006: ret 
} 

जो शाखा आप देख रहे हैं वह शायद डीबगर समर्थन के लिए है।

+0

मुझे उचित लगता है –

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