IL程序基本结构
IL代碼大致分為三部分:程序頭,各類聲明,代碼段
?
程序頭:主要是包括編譯后生成的可執行文件的一些屬性的定義,一般三個關鍵字
.assembly 聲明本程序集名稱
.assembly extern 聲明外部程序集名稱
.module? 聲明主模塊名稱
?
各類聲明:
.namespace 名稱空間聲明
.class 類聲明
.method 方法聲明
.field? 字段聲明
.data 數據聲明
.custom 自定義屬性聲明
?
代碼段:
主要由MSIL指令以及個別關鍵字構成,通常一個IL指令由操作碼(opcode)和指令參數(操作數operrand)構成,操作碼長度為1或2字節,當為2字節時,第一個字節總是0xFE
? 流程控制指令:
??? 1.直接跳轉指令
???? br 從當前位置移動到指定的位置
???? br .s?? br的短指令格式
?? 2.條件跳轉指令
????? brfalse? value為0則跳轉
????? brfalse.s??? 短指令格式
????? brtrue 不為0跳轉
????? brtrue.s? 短指令格式
? 3.比較跳轉
???? beq? 等于跳轉?? beq.s
???? bne.un 不等于跳轉?? bne.nu.s? 無符號
???? bge[.un.s] 大于或等于?
???? bgt[.un.s]???? 大于則跳轉??
???? ble[.un.s]???? 小于等于跳轉?
???? blt[.un.s]?? 小于跳轉?
???? un 標識無符號 s標識短指令
? 4.選擇指令
??? switch
? 5中斷指令
??? break
? 6 托管異常指令
???? leave[.s] 清空堆棧,跳至當前指令的偏移處。用于從try。。catch跳出
???? endfilter 表示filter塊的終結。
???? endfinally 表示finally或fault終結,并清空堆棧
? 7 返回指令
???? ret? 從一個方法返回
算術指令
? 1.堆棧操作
???? nop 空指令 無任何操作
???? dup 賦值當前棧頂元素
???? pop 出棧 堆棧為空時出錯
?? 2.常數載入
????? 用于將常數入棧
???? ldc.i4 載入int32
???? ldc.i4.s 載入int8
???? ldc.i4.ml 載入-1
???? ldc.i4.[0 ~8] 載入0~8;
???? ldc.i8 載入int64
???? ldc.r4 載入float32
???? ldc.r8 載入float64
?
3.間接載入
??? 間接載入指令從棧頂取出一個托管指針(&類型)或非托管指針(native int 類型),載入該指針所指向的數值,并入棧。指令中小數點后的名稱表明了載入數據的類型
?? ldind.i1/ ldind.u1 載入1字節無符號/有符號整數
?? ldind.i2/ldind.u2? 2字節
?? ldind.i4/ldind.u4? 4字節
?? ldind.i8/ldind.u8? 8字節
?? ldind.i??????????????? 載入native int 大小為當前系統的指針大小
??? ldind.r4/ldind.r8 載入單精度/雙精度浮點數據
??? ldind.ref??????????? 載入引用對象
4.間接存儲
間接存儲從棧頂先后取出一個值和指針,并將改值存儲至指針所指位置。
stind.ref? 存儲一個對象引用
stind.i1,i2,i4,i8 存儲1.2.4.8字節整數
? stind.i存儲一個指針大小的數據
? stind.r4,r8 存儲單精度、雙精度浮點數
5.算數運算
?? add 加?? sub 減? mul 乘? div除法? rem 模運算 neg 取反運算
?? 兩個特殊值:無限(infinity)和NaN(Not a Number)? 0*infinity=NaN
?? 0/0=NaN infinity/infinity=NaN x/infinity=0
??
6.位操作
? and 按位與 or 按位或? xor? 按位異或? not 按位求反
7 移位操作
?? shl 左移位 shr 右移位? shr.un無符號右移位
8.轉換指令
??? 從棧頂取值,進行相應轉換,將結果入棧。
??? conv.[類型]
??? conv.ovf.[類型]
9.邏輯條件檢測
?? ceq 是否相等? cgt[.un] 是否大于? clt [.un]是否小于? ckfiniter 取棧頂元素。當為NaN infinity拋出異常,否則入棧
10.塊操作
??? cpblk 復制一塊內存? initblk 初始化一塊內存
?
參數、局部變量與字段尋址
方法參數載入
? ldarg 載入一個方法參數
? ldarg.s短指令格式?
? ldarg[.0~4]載入第0~4個參數
方法參數地址載入 :ldarga[.s] 載入參數并入棧
方法參數存儲:????? starg[.s]?? 從棧頂取一個參數并存入參數
方法參數列表???????? arglist? 取得方法參數句柄 。。
局部變量載入? ldloc[.s][.0~3]載入第n個局部變量
局部變量引用載入 ldloca[.s] 載入局部變量的引用并入棧
局部變量保存?? stloc[.s] 從棧頂取值并存入局部變量
局部內存塊分配? localloc? 分配一塊局部內存塊
?
方法調用
? 直接調用:
jmp <token> (..) 放棄當前方法執行,直接跳轉至 token所指目標方法。
? call <token>(..) 以不通過v-able的方式調用一個instance或static方法
? callvirt<token>通過實例的v-table調用oken所指的方法。
間接調用
? ldftn?? ldvirtftn?? calli
尾部調用
tail
?
類與值操作
ldnull 讀取空的對象引用并入棧
ldobj? 從堆棧獲取值類型的托管指針
stobj 依次從堆棧取得值類型的值
ldstr? 讀取一個字符串
newobj 分配內存創建某個類的新實例
box 裝箱 unbox 拆箱
總結
- 上一篇: 凡客病毒式营销
- 下一篇: “jQuery风暴” 推荐及配套代码下载