ldc.i4.s和ldc.i4有什么区别?

时间:2014-02-03 04:56:16

标签: c# .net cil il

我正在研究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之间是否有任何区别。

编译器如何决定使用哪条指令(在这两条指令中)以及何时使用?

4 个答案:

答案 0 :(得分:8)

对于有符号字节值,编号

  

ldc.i4.s是一种更有效的编码,用于推送整数   -128到127进入评估堆栈。

请参阅MSDN

答案 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推入堆栈。基本指令