33 votes

IL Instructions non exposées par C #

Quelles instructions IL ne sont pas exposés en C#?

Je fais référence à des instructions comme sizeof et cpblk - il n'y a pas de classe ou de commande qui exécute ces instructions (sizeof en C# est calculée au moment de la compilation, et non pas au moment de l'exécution autant que je sache).

Les autres?

EDIT: La raison pour laquelle je vous pose cette question (et j'espère que cela va faire à ma question un peu plus valable), c'est parce que je suis en train de travailler sur une petite bibliothèque qui va fournir la fonctionnalité de ces instructions. sizeof et cpblk sont déjà mises en œuvre - je voulais savoir ce que les autres j'ai peut-être raté avant de passer.

EDIT2: à l'Aide d'Eric réponse, j'ai compilé une liste d'instructions:

  • Pause
  • Jmp
  • Calli
  • Cpobj
  • Ckfinite
  • Préfixe[1-7]
  • Prefixref
  • Endfilter
  • Non alignées
  • Tailcall
  • Cpblk
  • Initblk

Il y avait un certain nombre d'autres instructions qui n'ont pas été inclus dans la liste, je suis séparer parce qu'ils sont fondamentalement des raccourcis pour d'autres instructions (compressé pour économiser du temps et de l'espace):

  • Ldarg[0-3]
  • Ldloc[0-3]
  • Stloc[0-3]
  • Ldc_[I4_[M1/S/0-8]/I8/R4/R8]
  • Ldind_[I1/U1/I2/U2/I4/U4/I8/R4/R8]
  • Stind_[I1/I2/I4/I8/R4/R8]
  • Conv_[I1/I2/I4/I8/R4/R8/U4/U8/U2/U1]
  • Conv_Ovf_[I1/I2/I4/I8/U1/U2/U4/U8]
  • Conv_Ovf_[I1/I2/I4/I8/U1/U2/U4/U8]_Un
  • Ldelem_[I1/I2/I4/I8/U1/U2/U4/R4/R8]
  • Stelem_[I1/I2/I4/I8/R4/R8]

36voto

Eric Lippert Points 300275

Je fais référence à des instructions comme sizeof et cpblk - il n'y a pas de classe ou de commande qui exécute ces instructions (sizeof en C# est calculée au moment de la compilation, et non pas au moment de l'exécution autant que je sache).

Ceci est incorrect. sizeof(int) sera considérée comme la constante de compilation 4, bien sûr, mais il ya beaucoup de situations (tous, en unsafe code) où le compilateur s'appuie sur le moteur d'exécution pour déterminer quelle est la taille de la mémoire d'une structure. Considérons, par exemple, une structure qui contient deux pointeurs. Il serait de taille 8 sur un ordinateur 32 bits, mais 16 sur un ordinateur 64 bits. Dans ces circonstances, le compilateur va générer le sizeof opcode.

Les autres?

Je n'ai pas une liste de tous les opcodes que nous ne produisons pas -- je n'ai jamais eu besoin de construire une telle liste. Cependant, sur le dessus de ma tête, je peux vous dire qu'il n'existe aucun moyen pour générer un "appel indirect" (calli) l'instruction en C#; nous sommes parfois demandé pour cette fonction car elle permettrait d'améliorer les performances de certains scénarios d'interopérabilité.

Mise à JOUR: je viens de grepped le code source pour produire une liste d'opcodes nous avons certainement ne produire. Ils sont les suivants:

ajouter
add_ovf
add_ovf_un
et
arglist
beq
beq_s
bge
bge_s
bge_un
bge_un_s
bgt
bgt_s
bgt_un
bgt_un_s
ble
ble_s
ble_un
ble_un_s
blt
blt_s
blt_un
blt_un_s
bne_un
bne_un_s
boîte
br
br_s
brfalse
brfalse_s
brtrue
brtrue_s
appel
callvirt
castclass
ceq
la cgt
cgt_un
clt
clt_un
contraint
conv_i
conv_ovf_i
conv_ovf_i_un
conv_ovf_u
conv_ovf_u_un
conv_r
conv_r_un
conv_u
div
div_un
dup
endfinally
initobj
isinst
ldarg
ldarg_
ldarg_s
ldarga
ldarga_s
ldc_i
ldc_r
ldelem
ldelem_i
ldelem_r
ldelem_ref
ldelem_u
ldelema
ldfld
ldflda
ldftn
ldind_i
ldind_r
ldind_ref
ldind_u
ldlen
ldloc
ldloc_
ldloc_s
ldloca
ldloca_s
ldnull
ldobj
ldsfld
ldsflda
ldstr
ldtoken
ldvirtftn
laisser
leave_s
localloc
mkrefany
mul
mul_ovf
mul_ovf_un
neg
newarr
newobj
nop
pas
ou
pop
readonly
refanytype
refanyval
rem
rem_un
ret
rethrow
shl
shr
shr_un
sizeof
starg
starg_s
stelem
stelem_i
stelem_r
stelem_ref
stfld
stind_i
stind_r
stind_ref
stloc
stloc_s
stobj
stsfld
sous
sub_ovf
sub_ovf_un
commutateur
jeter
unbox_any
volatile
xor

Je ne vais pas vous garantir que c'est tout, mais c'est certainement la plupart d'entre eux. Vous pouvez ensuite comparer par rapport à une liste de tous les opcodes et voir ce qui est manquant.

13voto

ShuggyCoUk Points 24204

Basé sur Eric réponse ici sont certains que j'ai repéré. Où je peux voir une raison que j'ai indiquée, si je pas librement spéculer. Hésitez pas à l'indiquer si ces spéculations sont mauvais.

Break

Les signaux de la Common Language Infrastructure (CLI) pour informer le débogueur qu'un point de rupture a été déclenché.

Vous voudriez faire cela en Système d'appel.Diagnostics.Débogueur.Pause(), cela ne semble pas utiliser cette instruction directement, mais utilise à la place une BreakInternal() la méthode de boulangerie dans le CLR.

Cpblk et Cpobj

Des Copies d'un nombre spécifié d'octets à partir d'une adresse source vers une adresse de destination. Copie le type de la valeur située à l'adresse d'un objet (type &, * ou native int) à l'adresse de la destination de l'objet (type &, * ou native int).

Je suppose qu'ils ont été ajoutés pour le C++/CLI (précédemment Gérée C++), mais c'est purement de la spéculation de ma part. Ils peuvent également être présents dans certains appels système, mais pas normalement généré par le compilateur et la possibilité dangereux pour l'amusement et les jeux.

Endfilter

Transfère le contrôle à partir de la clause de filtre d'une exception à l'arrière de la Common Language Infrastructure (CLI) gestionnaire d'exception.

C# ne prend pas en charge l'exception de filtrage. Le compilateur visual basic, sans doute, rend l'utilisation de ce bien.

Initblk

Initialise un certain bloc de mémoire à une adresse précise, pour une taille donnée et la valeur initiale.

Je vais spéculer à nouveau que c'est potentiellement utile dans le code unsafe et C++/CLI

Jmp

Sorties méthode actuelle et les sauts à la méthode spécifiée.

Je vais supposer que ce genre de trampoline peut être utile pour ceux qui veulent éviter la queue des appels. Peut-être le DLR rend l'utilisation de celui-ci?

Tailcall

Effectue une suffixé appel de la méthode d'instruction, telles que la méthode actuelle du cadre de pile est retirée avant de l'appel, l'instruction est exécutée.

Discuté en profondeur ailleurs, actuellement, le compilateur c# n'émet pas de cet opcode

Unaligned

Indique qu'une adresse actuellement au sommet de la pile d'évaluation pourrait ne pas être aligné à la taille naturelle de la suit immédiatement ldind, stind, ldfld, stfld, ldobj, stobj, initblk, ou cpblk instruction.

C# (et le CLR) est tout à fait un peu de garanties concernant l'harmonisation de la nature d'une grande partie de son code et de données. Il n'est pas surprenant que ce n'est pas émise, mais je peux voir pourquoi il serait inclus.

Unbox

Convertit le texte de l'encadré de la représentation d'un type de valeur à ses unboxed forme.

Le compilateur c# préfère utiliser l' Unbox_Any enseignement exclusivement à cette fin. Je présume, basée sur l'addition de cela pour le jeu d'instruction dans la version 2.0, il fait des génériques soit feasibale, ou beaucoup plus simple. À ce point de l'utiliser dans le code pour tout, génériques ou autre, soit plus sûr, plus simple ou plus rapide (ou une combinaison de tous).


Note de bas de page:

Prefix1, Prefix2 Non Vides, Prefix3, Prefix4, Prefix5, Prefix6, Prefix7, Prefixref

L'Infrastructure. C'est réservé à l'enseignement.

Ce ne sont pas des instructions en tant que tel, Certaines instructions IL sont plus long que les autres. Ces de longueur variable doit commencer avec des préfixes qui ne sont jamais valables sur leur propre pour faire l'analyse claire. Ces préfixe opcodes sont réservés pour qu'ainsi ils ne sont pas utilisés ailleurs. Sans doute quelqu'un de la mise en œuvre d'une instruction switch d'analyseur de pour un IL séquence s'apprécient ces, de sorte qu'ils pourraient piéger ceux et maintenir l'état.

4voto

Andrey Points 36869

Un exemple intéressant est tail.call ( OpCodes.Tailcall ) qui rendrait possible l'optimisation d'appel final pour la récursivité.

1voto

Jordão Points 29221

La directive .override IL (je ne sais pas si c'est le terme correct, mais ce n'est certainement pas une instruction ) est générée par le compilateur C #, mais uniquement dans le cas particulier de la mise en œuvre d'interface explicite.

Il serait intéressant de pouvoir l'utiliser plus librement, comme dans VB.NET, où les membres d'implémentation peuvent être aliasés ou même avoir un modificateur d'accès différent de celui du membre d'interface.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X