Ich habe die IL code
eines einfachen Programms entdeckt:
Ich erstelle diesen Code im Modus Release und dieser IL code
wird generiert:
Ich finde so ziemlich alle Hinweise außer diesem:
%Vor% Nun sollte diese Anweisung int.MaxValue * 2L
auf den Stapel schieben und dann wird blt.s
mit i
vergleichen, wenn i
kleiner als der Wert ist, gehe zurück zu IL_0008
. Aber was kann ich? ' t herauszufinden, warum lädt es -2 ? Wenn ich die Schleife wie folgt ändere:
Es lädt den erwarteten Wert:
%Vor% Was bedeutet also -2
in diesem Code?
int.MaxValue * 2L
ist eine 64-Bit-Zahl, die jedoch immer noch in 32-Bits passt ( 4,294,967,294
, oder 0xFFFFFFFE
). Daher lädt der Compiler 0xFFFFFFFE
(was gleich -2 ist, wenn er als Int32
interpretiert wird) und erweitert ihn dann auf einen vorzeichenlosen 64-Bit-Wert.
Der Grund für die Verwendung des signierten Formulars ist, dass die Zahl, wenn sie als vorzeichenbehafteter Wert -2
interpretiert wird, in ein einzelnes signiertes Byte ( -128
bis 127
) passt, was bedeutet, dass der Compiler die Kurzform ldc.i4.s
Opcode, um einen 32-Bit-Wert von einem einzelnen Byte zu laden. Es brauchte nur 2 Bytes, um die 32-Bit-Ganzzahl mit Vorzeichen zu laden, und zusätzlich 1 Byte, um sie in einen 64-Bit-Wert zu konvertieren - das ist viel besser als eine 64-Bit-Ladeanweisung, gefolgt von einer vollen 8-Byte-Ganzzahl ohne Vorzeichen / p>
Es sieht so aus, als ob der Compiler bitweise Mathematik zu seinem Vorteil benutzt. Es passiert einfach, dass der Two-Komplement -Wert von -2 gleich dem vorzeichenlosen Integer-Wert von (int.MaxValue) ist * 2L)
In der bitweisen Darstellung:
%Vor%Tags und Links c# cil il intermediate-language