【.Net底層剖析】2.stfld指令-給對象的字段賦值


.Net底層剖析目錄章節

1.【深入淺出.Net IL】1.一個For循環引發的IL 

2.【.Net底層剖析】2.stfld指令-給對象的字段賦值

3.【.Net底層剖析】3.用IL來理解屬性

 

引言:

  這篇我們講解在.net  IL中間語言中,經常見到的指令stfld

  該指令經常用在給一個對象的字段賦值。

 一、指令用途:

  MSDN解釋如下:

  Replaces the value stored in the field of an object reference or pointer with a new value.

  翻譯過來就是:用一個新值替換對象字段的值

二、命名空間和程序集

  命名空間是在  System.Reflection.Emit這個里面

  程序集是mscorlib(mscorlib.dll)

 三、指令執行機制

  工作原理即堆棧轉換行為如下:

  按照先后順序:

    1.將一個對象引用或指針壓入堆棧

    2.將值被壓入堆棧

    3.該值和對象的引用/指針從堆棧中彈出,對象的字段更新為替換的值

四、 實例代碼分析:

C#程序:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test test1=new Test();//new一個Test對象
            test1.i = 12;//將Test對象的字段i賦值為12
        }

        /// <summary>
        /// 測試類
        /// </summary>
        public class Test
        {
            public int i = 100;
        }
    }
}

 

IL 程序Main方法

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       16 (0x10)
  .maxstack  2
  .locals init ([0] class ConsoleApplication1.Program/Test test1)
  IL_0000:  nop
  IL_0001:  newobj     instance void ConsoleApplication1.Program/Test::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.s   12
  IL_000a:  stfld      int32 ConsoleApplication1.Program/Test::i
  IL_000f:  ret
} // end of method Program::Main

我們來逐行分析下main方法的IL代碼

.entrypoint  //定義函數的入口點

  // Code size       16 (0x10)//代碼大小為16

  .maxstack  2//棧的大小為2

  .locals init ([0] class ConsoleApplication1.Program/Test test1)//定義一個變量為test1,存儲在<本地變量列表>中第一個變量中

  IL_0000:  nop//空操作

  IL_0001:  newobj     instance void ConsoleApplication1.Program/Test::.ctor()//new 一個Test對象,一個引用指向這個對象,引用存放在棧上,

對象存放在堆上面

  IL_0006:  stloc.0//將引用彈棧,存放到<本地變量列表>中的第一個變量中

  IL_0007:  ldloc.0//<本地變量列表>中第一個變量的值壓入堆棧

  IL_0008:  ldc.i4.s   12//int 12壓入堆棧

  IL_000a:  stfld      int32 ConsoleApplication1.Program/Test::i//將堆棧的棧頂的值賦值給堆棧的第二個值,即test.i=12

  IL_000f:  ret//函數返回

 五、內存分析

在指令stfld 執行之前的內存圖

 

 

堆棧中存放12test1的地址,<本地變量列表>第一個變量中存放的是test1的地址,堆中存放的是test1指向的一個對象,其中test1.i=100

 

在指令stfld 執行之后的內存圖

 

 

 

 

堆棧中的12test1的地址彈出,<本地變量列表>第一個變量中存放的是test1的地址不變,堆中存放的是test1.i=12

 

六、總結

本篇主要講的就是對象的字段如何在內存中是如何賦值的,以及從每一行IL指令分析stfld 的執行過程。從底層分析對象的字段的賦值,可以更加清晰地看到賦值的過程。

 

下篇我會從.net底層剖析參數的傳遞,有興趣的可以關注我哦!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM