歷經艱難之後,現在,你終於看到了成功,並明白我們為什麼想要你首先閱讀本書了。
讓我們理解上面的代碼,每次一個字段。我們創建了一個靜態變量i,並將其初始化為值6。由於 沒有為變量i指定一個訪問修飾符,默認值就是private。C#中的修飾符static也適用於IL中的變量。
實際的操作現在才開始。變量需要被分配一個初始值。這個值必須只能在靜態改造函數中分配, 因為變量是靜態的。我們使用ldc來把值6放到棧上。注意到這裡並沒有使用到locals指令。
為了 初始化i,我們使用了stsfld指令,用於在棧頂尋找值。stsfld指令的下一個參數是字節數量,它必須從 棧上取得,用來初始化靜態變量。在這個例子中,指定的字節數量是4。
變量名稱位於類的名稱之 前。這與局部變量的語法正好相反。
對於實例變量j,由於它的訪問修飾符是C#中的public,轉換 到IL,它的訪問修飾符保留為public。由於它是一個實例變量,所以它的值會在實例變量中初始化。這裡 使用到的指令是stfld而不是stsfld。這裡我們需要棧上的8個字節。
剩下的代碼和從前保持一致 。因此,我們可以看到stloc指令被用於初始化局部變量,而stfld指令則用於初始化字段。
a.cs
class zzz
{
static int i = 6;
public long j = 7;
public static void Main()
{
new zzz();
}
static zzz()
{
System.Console.WriteLine("zzzs");
}
zzz()
{
System.Console.WriteLine("zzzi");
}
}
a.il
.assembly mukhi {}
.class private auto ansi zzz extends System.Object
{
.fIEld private static int32 i
.fIEld public int64 j
.method public hidebysig static void vijay() il managed
{
.entrypoint
newobj instance void zzz::.ctor()
pop
ret
}
.method public hidebysig specialname rtspecialname static void .cctor() il managed
{
ldc.i4.6
stsfld int32 zzz::i
ldstr "zzzs"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() il managed
{
ldarg.0
ldc.i4.7
conv.i8
stfld int64 zzz::j
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ldstr "zzzi"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
}
Output
zzzs
zzzi