我正在研究C#(IL)的中间语言,并且遇到了以下代码: -
//Add.il
//Add Two Numbers
.assembly extern mscorlib {}
.assembly Add
{
.ver 1:0:1:0
}
.module add.exe
.method static void main() cil managed
{
.maxstack 2
.entrypoint
ldstr "The sum of 50 and 30 is = "
call void [mscorlib]System.Console::Write (string)
ldc.i4.s 50
ldc.i4 30
add
call void [mscorlib]System.Console::Write (int32)
ret
}
我是理解IL的初学者,但我知道上面例子中Main
中使用的这些非常基本的指令的含义。
我的问题是,用于加载50的指令ldc.i4.s
和用于将30加载到评估堆栈的指令ldc.i4
之间是否有任何区别。
编译器如何决定使用哪条指令(在这两条指令中)以及何时使用?
答案 0 :(得分:8)
答案 1 :(得分:3)
当您的值介于-128 to 127
之间时,您可以ldc.i4.s。
ldc.i4.s是一种更有效的编码,用于将整数从-128推送到127到评估堆栈。
答案 2 :(得分:2)
不同之处在于ldc.i4.s
只能在操作数适合有符号字节(-128到127(含))时使用。好处是产生的IL更短,节省了程序空间。这很有用,因为许多常量负载使用小常量。
答案 3 :(得分:1)
<强> ldc.i4.s 强>
将int32类型的数字作为int32推送到堆栈中。按类型int32的-1 作为int32(ldc.i4.m1的别名)到堆栈上。将num推入堆栈 作为int32,简短形式。将int类型的num作为int64推送到堆栈。
OpCode:0x1F
说明:ldc.i4.s
描述:将num作为int32(短格式)压入堆栈。
<强> ldc.i4 强>
将int32类型的-1作为int32(ldc.i4.m1的别名)压入堆栈。 将num作为int32(短格式)压入堆栈。推送类型为int64的num 作为int64进入堆栈。将float32类型的数字推送到堆栈上,作为F。
OpCode:0x20
说明:ldc.i4
描述:将int32类型的num作为int32推入堆栈。基本指令