IL閱讀第二篇,拆箱裝箱

            //裝箱拆箱
            string name = "Zery";
            int age = 22;
            Console.WriteLine(age.ToString() + name);//已ToString的操作
            Console.WriteLine(age+name);//未ToString操作

老規矩,一段C#,一段IL

	// Method begins at RVA 0x2050
	// Code size 48 (0x30)
	.maxstack 2
	.entrypoint
	.locals init (
		[0] string name,
		[1] int32 age
	)

	IL_0000: nop
	IL_0001: ldstr "Zery"
	IL_0006: stloc.0
	IL_0007: ldc.i4.s 22
	IL_0009: stloc.1
	IL_000a: ldloca.s age
	IL_000c: call instance string [mscorlib]System.Int32::ToString()
	IL_0011: ldloc.0
	IL_0012: call string [mscorlib]System.String::Concat(string, string)
	IL_0017: call void [mscorlib]System.Console::WriteLine(string)
	IL_001c: nop
	IL_001d: ldloc.1
	IL_001e: box [mscorlib]System.Int32
	IL_0023: ldloc.0
	IL_0024: call string [mscorlib]System.String::Concat(object, object)
	IL_0029: call void [mscorlib]System.Console::WriteLine(string)
	IL_002e: nop
	IL_002f: ret

 

第一段:
IL_0000: nop以上的之前有過介紹,這次不做介紹
ldstr:推送對元數據中存儲的字符串的新對象引用。
stloc.0加載到索引變量的第一位
ldc.i4.s:將位於特定索引處的局部變量的地址加載到計算堆棧上(短格式)。
stloc.1加載到索引變量的第二位
賦值之前一篇也講過,這裏不詳細


IL_000a: ldloca.s age
IL_000c: call instance string [mscorlib]System.Int32::ToString()
IL_0011: ldloc.0
第二段:
ldloca.s :將位於特定索引處的局部變量的地址加載到計算堆棧上。
意思是將string類型的age變量,壓入計算棧中
然後調用函數ToString,並將結果壓入棧中
ldloc.0:將索引 0 處的局部變量加載到計算堆棧上。這樣棧上就有兩個了


IL_0012: call string [mscorlib]System.String::Concat(string, string)
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
第三段:
棧彈出兩個量,然後執行Concat,返回的值壓入棧,
再彈出一個量,在執行WriteLine。


IL_001c: nop
IL_001d: ldloc.1
IL_001e: box [mscorlib]System.Int32
IL_0023: ldloc.0
第四段:

Box:將值類轉換爲對象引用(O 類型)。
裝箱box,先將第二個變量值壓入計算棧,然後執行box裝箱(填出棧,做box操作,返回值壓入棧),再壓入第一個變量的值


IL_0024: call string [mscorlib]System.String::Concat(object, object)
IL_0029: call void [mscorlib]System.Console::WriteLine(string)
IL_002e: nop
IL_002f: ret
第五段:
棧中彈出兩個量執行Concat函數,返回值壓入棧
棧中彈出一個量執行WriteLine

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章