C# NET JIT如何确定如何添加数字

C# NET JIT如何确定如何添加数字,c#,clr,jit,cil,opcode,C#,Clr,Jit,Cil,Opcode,CIL有一个操作码,用于在不进行溢出检查的情况下添加数字-add 此C#代码: 生成以下IL代码: IL_0000: ldc.i4.s 10 IL_0002: stloc.0 IL_0003: ldc.i4.s 20 IL_0005: stloc.1 IL_0006: ldloc.0 IL_0007: ldloc.1 IL_0008: add IL_0009: stloc.2 JIT在运行时如何确定应该使用哪种类型的x86加法(FPU操作码faddp用于浮点数或add用

CIL有一个操作码,用于在不进行溢出检查的情况下添加数字-add

此C#代码:

生成以下IL代码:

IL_0000:  ldc.i4.s   10
IL_0002:  stloc.0
IL_0003:  ldc.i4.s   20
IL_0005:  stloc.1
IL_0006:  ldloc.0
IL_0007:  ldloc.1
IL_0008:  add
IL_0009:  stloc.2

JIT在运行时如何确定应该使用哪种类型的x86加法(FPU操作码faddp用于浮点数或add用于整数)?

CLR跟踪求值堆栈上的值类型,因此它知道就在
add
指令之前,堆栈上最顶端的两个值的类型是代码中的
int32
。这意味着它知道它必须发出添加32位整数的指令


如果您编写的代码中CLR无法找出
add
的操作数类型,那么您的代码将无法验证,并且可能会产生垃圾本机代码。

不熟悉IL,但出于这个原因不是“i4”吗?意思是“int,4字节”?这意味着类型数据会一直保存到add。我认为就是这样-将
int
更改为
float
会生成
r4
double
r8
…NET IL不像Java字节码,只有一个add。它被设计成总是被编译的,而不是被解释的。在生成代码的过程中,jitter始终可以找出操作数类型,从而选择正确的机器代码指令。
IL_0000:  ldc.i4.s   10
IL_0002:  stloc.0
IL_0003:  ldc.i4.s   20
IL_0005:  stloc.1
IL_0006:  ldloc.0
IL_0007:  ldloc.1
IL_0008:  add
IL_0009:  stloc.2