指令格式 | 英文單詞全寫 | 指令解釋 | |
---|---|---|---|
nop | no operation performed | 不做任何操作址貌,留待后續(xù)版本補(bǔ)齊此操作碼功能 | |
ldc.i4 num | load const | 將操作常數(shù)數(shù)num推送到計(jì)算堆棧. 其中i4代表int32常數(shù),棧頂結(jié)果為int32; ldc.i8欺旧,代表推送int64常數(shù),結(jié)果為int64; ldc.i4.s偿曙,代表推送int8悠瞬,結(jié)果為int32; ldc.i4.m1昵骤,代表推送-1(minus 1),結(jié)果為int32; ldc.r4交惯,代表推送float32次泽,結(jié)果為float32; ldc.r8,代表推送float64商玫,結(jié)果為float64; |
|
ldloc n | load local | 加載第n個(gè)本地變量到計(jì)算堆棧; ldloc.n牡借,n取0~3拳昌,代表加載n處的本地變量; ldloc.s n,短格式钠龙,針對(duì)0~255之間數(shù)值炬藤,更高效; |
|
ldloca index | load local | 加載第n個(gè)本地變量的地址到計(jì)算堆棧; ldloca.s 短格式 |
|
stloc.n | stack local | 彈出計(jì)算堆棧上的棧頂元素碴里,存儲(chǔ)到本地變量列表(即調(diào)用堆棧)的第n個(gè)位置沈矿,即賦值給第n個(gè)局部變量(函數(shù)參數(shù)也被編譯為局部變量) | |
box valTypeToken | box | 裝箱,將值類型封裝成valTypeToken指定的對(duì)象類型咬腋,流程是羹膳,彈出計(jì)算堆棧上的值類型參數(shù),并使用新建立的一個(gè)引用類型對(duì)象進(jìn)行并包裝根竿,將包裝結(jié)果返回計(jì)算堆棧陵像。本過(guò)程產(chǎn)生GC Alloc就珠。 | |
unbox valType | unbox | 拆箱,將引用類型轉(zhuǎn)換成相應(yīng)值類型valType醒颖,流程是妻怎,彈出計(jì)算堆棧上的引用類型參數(shù),并執(zhí)行拆箱轉(zhuǎn)換泞歉,將轉(zhuǎn)換完成的值類型結(jié)果推送回計(jì)算堆棧 | |
unbox.any typeTok | unbox any | 拆箱逼侦,將引用類型轉(zhuǎn)換成相應(yīng)值類型或者引用類型typeTok,流程與unbox相同腰耙,差別是榛丢,如果typeTok是值類型,則與unbox相同沟优;如果typeTok是引用類型涕滋,則與castclass相同,即執(zhí)行類型轉(zhuǎn)換 | |
castclass classT | cast class | 強(qiáng)制類型轉(zhuǎn)換挠阁,流程是宾肺,將計(jì)算堆棧上的參數(shù)彈出,并驗(yàn)證其是否是繼承了classT指定的class侵俗,或者實(shí)現(xiàn)于classT指定的接口锨用,如果不是,則引發(fā)轉(zhuǎn)換異常隘谣;如果轉(zhuǎn)換正常增拥,則把轉(zhuǎn)換后的結(jié)果引用返回;如果當(dāng)前的參數(shù)本身是null寻歧,則也返回null | |
initobj typeTok | init object | 將當(dāng)前計(jì)算堆棧棧頂單元視為某個(gè)值類型對(duì)象的地址掌栅,調(diào)用值類型typeTok的初始化方法,將此地址指向的值類型單元置為0码泛,與newobj指令不同 猾封,initobj不調(diào)用構(gòu)造函數(shù)方法。 | |
call methodDesc | call method description | 應(yīng)用于早綁定的函數(shù)調(diào)用噪珊,即它不會(huì)考慮函數(shù)重載晌缘。在函數(shù)調(diào)用之前,傳遞的參數(shù)應(yīng)該已經(jīng)被壓到計(jì)算堆棧上痢站,此時(shí)執(zhí)行call指令磷箕,執(zhí)行完成之后,將會(huì)執(zhí)行ret指令阵难,并將返回值存儲(chǔ)到計(jì)算堆棧岳枷。 | |
callvirt method | call method | 應(yīng)用于晚綁定的函數(shù)調(diào)用,即它會(huì)計(jì)算函數(shù)重載。除此之外嫩舟,其運(yùn)行步驟與call相同氢烘。【每個(gè)函數(shù)調(diào)用起始家厌,都會(huì)有2句話max stack ...;.locals init(...)播玖,是否是由它們彈出當(dāng)前計(jì)算堆棧上的參數(shù),并存放到當(dāng)前的局部變量列表(Call Stack)中饭于,所以在返回時(shí)蜀踏,不用關(guān)心之前壓入?yún)?shù)占據(jù)堆棧單元的問(wèn)題?】 | |
ret | return | 從當(dāng)前函數(shù)返回掰吕,并且將返回值從當(dāng)前函數(shù)的計(jì)算堆棧推送到調(diào)用者函數(shù)的計(jì)算堆棧 | |
newobj ctor | new object constructor | 創(chuàng)建一個(gè)新引用類型或者值類型對(duì)象實(shí)例果覆,并將創(chuàng)建出來(lái)的引用壓入計(jì)算堆棧,并調(diào)用其后面跟隨的ctor構(gòu)造函數(shù)殖熟。如果當(dāng)前創(chuàng)建的是值類型對(duì)象局待,那么它壓入當(dāng)前堆棧的是內(nèi)存地址位于當(dāng)前堆棧上的對(duì)象引用。當(dāng)應(yīng)用于引用類型時(shí)菱属,此方法會(huì)產(chǎn)生GCAlloc钳榨。 |
需要注意以下幾點(diǎn):
- 所有的對(duì)象類型繼承自System.Object類,所有的值類型繼承自System.ValueType類纽门。
- 不是所有的newobj 指令都會(huì)產(chǎn)生新的GC Alloc薛耻。當(dāng)它應(yīng)用值類型時(shí),就會(huì)在當(dāng)前計(jì)算堆棧上構(gòu)建Object赏陵,而不需要存放至堆饼齿。
- 不是所有的new A() 代碼,都會(huì)被翻譯成IL中的newobj指令蝙搔。當(dāng)A是對(duì)象類型時(shí)缕溉,一定轉(zhuǎn)換成newobj;當(dāng)A時(shí)值類型時(shí)吃型,就有可能轉(zhuǎn)換成newobj证鸥,也有可能轉(zhuǎn)換成initobj,取決于是否需要執(zhí)行構(gòu)造函數(shù)败玉。
- box指令敌土,即裝箱指令镜硕,是將值類型封裝成對(duì)象類型的一個(gè)過(guò)程运翼。必然產(chǎn)生新的GC Alloc。