当我这样做时,什么情况发生在低水平?
Int32 a = 0;
Int16 b = 50;
a = b;
答案 0 :(得分:7)
这样的事情:
IL_0001: /* 1F | 32 */ ldc.i4.s 50
IL_0003: /* 0B | */ stloc.1
IL_0004: /* 07 | */ ldloc.1
IL_0005: /* 0A | */ stloc.0
在较低级别,它取决于机器架构和优化级别。像这样的代码,没有任何影响,可能只是完全省略。否则,它将是简单的代码,也许是这样:
movsx eax, word ptr [ebp+12]
mov [ebp+8], eax
movsx
是x86指令,当它被加载到更大的目的地时保留较短数字的符号;基本上,它会查看较小源的最高位,并在扩展数字时将其复制到剩余的位中。
答案 1 :(得分:2)
来自Reflector:
.method public hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] int32 num,
[1] int16 num2)
L_0000: nop
L_0001: ldc.i4.0 ; Load the constant 0
L_0002: stloc.0 ; Store the value into local var 0
L_0003: ldc.i4.s 50 ; Load the constant 50 - notice it treats it as a 32-bit value
L_0005: stloc.1 ; Store the value into local var 1
L_0006: ldloc.1 ; Load local var 1
L_0007: stloc.0 ; Store the value into local var 0
L_0008: ret
}
在IL级别,赋值中没有任何特殊情况,但请注意ldc.i4.s 50
将字面值视为4字节(32位)整数。
当代码是JIT编译时,生成的汇编代码可能只是将值50提升到32位宽的值。
答案 2 :(得分:0)
评估堆栈的表示形式不小于32位。 [编辑,在大多数情况下(感谢评论更新:)]直到你实际存储除堆栈之外的其他地方的16位值,没有特殊发生,因为short
和int
的大小相同。以下是您将看到差异的唯一操作:
b = (short)a
conv.i4
指令。*(short*)c = b
或分配给结构成员,其结构标记为StructLayout.Explicit
或包装小于4. checked { b = (short)a; }
(a < -32768 || a > 32767)
。