2015-11-13 36 views
5

तो मैं ILDASM पर एक दृष्टि डाली, एक .exe जो इस तरह दिखता निरीक्षण:== ऑपरेटर वास्तव में क्या करता है?

int a = 2; 
Int32 b = 1; 
if(b == 1) 
{ 

} 

अब सीआईएल कोड कि तरह लग रहा है:

IL_0005: ldloc.1 
IL_0006: ldc.i4.1 
IL_0007: ceq 
IL_0009: ldc.i4.0 
IL_000a: ceq 
IL_000c: stloc.2 

मैं समझता हूँ कि पहले ख भरी हुई है (जो [1] पर संग्रहीत है), फिर 1 के मान के साथ एक स्थिर और फिर उनकी तुलना की जाती है। मुझे समझ में नहीं आता है कि उस तुलना के परिणाम से पहले मूल्य 0 के साथ एक और स्थिर लोड और तुलना की जाती है।
चूंकि पहली तुलना पहले से ही एक सत्य मूल्य उत्पन्न करनी चाहिए, यह जांचना कि क्या यह मान 0 परिणाम को बदल देता है, है ना?
मेरा प्रश्न अब है: यह उलटा क्यों है? मुझे लगता है कि यह == ऑपरेटर के साथ कुछ करने के लिए है जिसका मैंने उपयोग किया था और मेरा सिद्धांत यह है कि यह अंतर देता है। यदि यह अंतर 0 है, तो मान समान हैं, इसलिए परिणाम होना चाहिए। लेकिन 0 झूठ के लिए खड़ा है, इसलिए इसे उलटा होना चाहिए।
मुझे इस विषय के बारे में कुछ भी नहीं मिल रहा है, बस ऑपरेटर जैसे == ~ या पसंद के बारे में कुछ। आशा है कि आप मुझे प्रबुद्ध कर सकते हैं :)

सादर

Wilsu

पुनश्च: यह पूरा कोड है:

.method private hidebysig instance void Form1_Load(object sender, 
               class [mscorlib] 
System.EventArgs e) cil managed 
{ 
// Code size  19 (0x13) 

.maxstack 2 
.locals init ([0] int32 a, 
     [1] int32 b, 
     [2] bool CS$4$0000) 
IL_0000: nop 
IL_0001: ldc.i4.2 
IL_0002: stloc.0 
IL_0003: ldc.i4.1 
IL_0004: stloc.1 
IL_0005: ldloc.1 
IL_0006: ldc.i4.1 
IL_0007: ceq 
IL_0009: ldc.i4.0 
IL_000a: ceq 
IL_000c: stloc.2 
IL_000d: ldloc.2 
IL_000e: brtrue.s IL_0012 
IL_0010: nop 
IL_0011: nop 
IL_0012: ret 
} // end of method Form1::Form1_Load 
+1

मुझे वह आईएल बिल्कुल नहीं मिला। मेरा अनुमान है कि यह कोड के दूसरे टुकड़े से है। कृपया एक छोटा लेकिन * पूरा * उदाहरण पोस्ट करें। –

+0

मुझे मुख्य रूप से केवल इस कोड के साथ वही मिलता है (कम से कम समान परिणाम)। – Rob

+0

क्या आप रिलीज में संकलित हैं? (मुझे कोई भी "एनओपी" नहीं दिख रहा है, लेकिन ...), और: क्या यह * पूरा * कोड है? ऐसा लगता है कि उसने कुछ मजेदार पुन: ऑर्डरिंग की है; पी लेकिन: मुझे तीसरा चर नहीं दिख रहा है, इसलिए यह मेरे लिए स्पष्ट नहीं है कि 'stloc.2' भी * मतलब * ... –

उत्तर

1

यह समारोह के अंत में एक कूद कर रहा है, जहां तक ​​मैं इकट्ठा कर सकता हूं।

void Main() 
{ 
    int a = 2; 
    Int32 b = 1; 
    if(b == 1) 
    { 
     Console.WriteLine("A"); 
    } 
} 

मुझे देता है:

IL_0000: nop   
IL_0001: ldc.i4.2  
IL_0002: stloc.0  // a 
IL_0003: ldc.i4.1  
IL_0004: stloc.1  // b 
IL_0005: ldloc.1  // b 
IL_0006: ldc.i4.1  
IL_0007: ceq   
IL_0009: ldc.i4.0  
IL_000A: ceq   
IL_000C: stloc.2  // CS$4$0000 
IL_000D: ldloc.2  // CS$4$0000 
IL_000E: brtrue.s IL_001D 
IL_0010: nop   
IL_0011: ldstr  "A" 
IL_0016: call  System.Console.WriteLine 
IL_001B: nop   
IL_001C: nop   
IL_001D: ret   

IL_0005 से शुरू, हमने:

लोड b
लोड 1
ceq (बराबर हैं, तो धक्का 1, अगर झूठी धक्का 0) - यहाँ परिणाम 0
brtrue.s IL_001D होगा - - यदि मान गैर-शून्य है, IL_001D के लिए कूद (अंत यहाँ परिणाम 1
लोड 0
ceq हो जाएगा समारोह के)

तो यह अनिवार्य रूप से यह करने के लिए तैयार की है:

int a = 2; 
Int32 b = 1; 
if(!(b == 1)) 
    goto end; 
Console.WriteLine("A"); 
:end 
return; 
+2

, जब मैं इसे संकलित करता हूं (अनुकूलित) मुझे मिलता है: 'ldc.i4.1',' ldc.i4.1', 'bne.un.s {ret to}', 'ldstr" ए "', 'कॉल शून्य [mscorlib] सिस्टम। कंसोल :: लिखित रेखा (स्ट्रिंग) ',' ret' - बहुत अलग –

+0

हालांकि स्पष्ट रूप से मैं थोड़ी निराश हूं कि उसने इसे पूरी तरह से हटाया नहीं है और दो स्थिरांक की तुलना के बाद' ret' को संकलित नहीं किया है रनटाइम पर लगता है ... गूंगा –

+0

बहुत बहुत धन्यवाद, यही वही है जो मैं जानना चाहता था। – Wilsu

3

ceq स्टैक से दो मान लेता है और परिणाम 1 में होते हैं यदि उन्हें बराबर माना जाता है, और 0 यदि वे नहीं हैं। हालांकि, चाहे ceq में सी # परिणामों में == बहुत कुछ पर निर्भर करता है:

  • डेटा प्रकार
    • वे primatives कर रहे हैं?
    • क्या उनके पास कस्टम == ऑपरेटर हैं?
    • क्या वे संदर्भ हैं?
  • संदर्भ
    • यह कुछ और करने के लिए अनुकूलित किया जा सकता है? (मुझे एक उदाहरण में bne.un.s मिलता है; beq*, br*, switch, आदि)
    • इसे पूरी तरह से हटाया जा सकता है?
+0

डेटा प्रकारों के संबंध में: यही कारण है कि मैंने पूर्णांक का उपयोग किया। आदिम डेटा प्रकार, कोई ओवरलोडेड ऑपरेटर नहीं। यह मेरे दिमाग को कभी पार नहीं कर पाया कि == ऑपरेटर की तरह कुछ संभवतः सरल कुछ और अनुकूलित किया जा सकता है ... आपको मुझे दिलचस्पी है, मैं अब भी bne.un.s पर एक नज़र डालेगा। आपके समय के लिए शुक्रिया। – Wilsu

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