int3264ビットにを追加する場合native int、CLRは32ビット整数を符号拡張しますか、それともゼロ拡張しますか?そして最も重要なのは、どのような情報に基づいてこの選択を行うのかということです。
.NETコンパイラを作成していて、ECMA仕様をよく読んでいますが、答えが見つかりませんでした。
int32CLIは、評価スタックに格納されている値、、、int64およびの操作で、これらのタイプのサブセットのみをサポートしますnative int。
--ECMA 335、セクションI 12.1:サポートされているデータ型
評価スタックの値には符号付きの情報がないため、オペランドの符号が重要な命令には、符号付き整数用と符号なし整数用の2つのバリアントがあります。、および命令(オーバーフローをチェックしない命令)は、オペランドが同じサイズである限り、オペランドの符号を気にする必要はありません。したがって、バリアントは1つだけですadd。ただし、オペランドは常に同じサイズであるとは限りません。submul
ECMA 335、セクションIII 1.5:オペランドタイプの表には、anint32とanative intを加算、減算、乗算、および除算できると記載されています。結果は再びnative intです。64ビットシステムでは、anative intは64ビット幅です。
ldc.i4.0 // Load int32 0
conv.i // Convert to (64-bit) native int
ldc.i4.m1 // Load int32 -1
add // Add native int 0 and int32 0xFFFFFFFF together
では、ここでの結果はどうなるでしょうか?仕様によれば、ランタイムはスタック上の値の正確な型や符号を追跡する必要がないことに注意してください。ランタイムは、、int32およびint64(native intおよびここでは関係のない他のいくつか)のみを認識します。
算術演算は、内部的にネイティブintとして表されるため、この種の加算も使用するIntPtrと思います。UIntPtrただし、ILSpyは、C#にanIntPtrとaを追加するとInt32、クラスでオーバーロードされた+演算子が呼び出され、符号付き引数IntPtrのみを受け入れることを示しています。Int32
(命令を使用して)CILで直接add実行することは、整数が署名されていると解釈されることも示します。これもMonoで実装されているはずですが、調査結果を裏付けるための参照が見つかりませんでした。