IL Instrucciones no expuestas por C#


¿Qué instrucciones IL no están expuestas por C#?

Me refiero a instrucciones como sizeof y cpblk - no hay ninguna clase o comando que ejecute estas instrucciones (sizeof en C# se calcula en tiempo de compilación, no en tiempo de ejecución AFAIK).

Otros?

EDITAR: La razón por la que estoy haciendo esto (y espero que esto haga mi pregunta un poco más válida) es porque estoy trabajando en una pequeña biblioteca que proporcionará la funcionalidad de estas instrucciones. sizeof y cpblk son ya implementado-Quería saber qué otros puede que me haya perdido antes de seguir adelante.

EDIT2: Usando la respuesta de Eric, he compilado una lista de instrucciones:

  • Break
  • Jmp
  • Calli
  • Cpobj
  • Ckfinite
  • Prefijo[1-7]
  • Prefixref
  • Filtro final
  • No alineados
  • Tailcall
  • Cpblk
  • Initblk

Había una serie de otras instrucciones que no estaban incluidas en la lista, que estoy separando porque son básicamente atajos para otras instrucciones (comprimido para ahorrar tiempo y espacio):

  • 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]
Author: YellPika, 2011-08-18

4 answers

Me refiero a instrucciones como sizeof y cpblk - no hay ninguna clase o comando que ejecute estas instrucciones (sizeof en C# se calcula en tiempo de compilación, no en tiempo de ejecución AFAIK).

, Esto es incorrecto. sizeof(int) se tratará como la constante de tiempo de compilación 4, por supuesto, pero hay muchas situaciones (todas en el código unsafe) donde el compilador se basa en el tiempo de ejecución para determinar cuál es el tamaño de memoria de una estructura. Considere, por ejemplo, una estructura que contiene dos puntos. Sería de tamaño 8 en una máquina de 32 bits pero 16 en una máquina de 64 bits. En esas circunstancias, el compilador generará el sizeof opcode.

Otros?

No tengo una lista de todos los opcodes que no producimos never nunca he tenido la necesidad de construir una lista de este tipo. Sin embargo, en la parte superior de mi cabeza puedo decirle que no hay manera de generar una instrucción "call indirect" (calli) en C#; ocasionalmente se nos pide esa característica, ya que mejoraría rendimiento de ciertos escenarios de interop.

ACTUALIZAR: Acabo de greped el código fuente para producir una lista de opcodes definitivamente hacer producir. Le

No voy a garantizar que eso sea todo, pero eso es ciertamente la mayoría de ellos. A continuación, puede comparar con una lista de todos los opcodes y ver lo que falta.

 36
Author: Eric Lippert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-19 20:27:48

Basado en la respuesta de Eric aquí hay algunos que he visto. Donde puedo ver una razón la he indicado, si no especulo libremente. Siéntase libre de indicar si esas especulaciones están equivocadas.

Break

Señala a la Infraestructura de Lenguaje Común (CLI) para informar al depurador que se ha disparado un punto de interrupción.

Usted haría esto llamando al Sistema.Diagnostico.Depurador.Break (), esto parece no usar esa instrucción directamente, sino que usa un Método BreakInternal() cocido en el CLR.

Cpblk y Cpobj

Copia un número especificado de bytes de una dirección de origen a una dirección de destino. Copia el tipo de valor ubicado en la dirección de un objeto (type &, * o native int) a la dirección del objeto de destino (type &, * o native int).

Supongo que se agregaron para C++/CLI (anteriormente C++ Administrado), pero eso es pura especulación de mi parte. También pueden estar presente en ciertas llamadas al sistema pero no generadas normalmente por el compilador y proporcionar cierto margen para juegos y diversión inseguros.

Endfilter

Transfiere el control de la cláusula filter de una excepción al controlador de excepciones de Common Language Infrastructure (CLI).

C# no admite el filtrado de excepciones. El compilador VB sin duda hace uso de esto sin embargo.

Initblk

Inicializa una bloque de memoria especificado en una dirección específica a un tamaño y valor inicial dados.

Voy a especular de nuevo que esto es potencialmente útil en código inseguro y C++/CLI

Jmp

Sale del método actual y salta al método especificado.

Voy a especular que este tipo de trampolín puede ser útil para aquellos que quieren evitar llamadas de cola. Tal vez el DLR hace uso de ella?

Tailcall

Realiza una instrucción de llamada de método postfixed tal que el marco de pila del método actual se elimina antes de que se ejecute la instrucción de llamada real.

Discutido en profundidad en otra parte, actualmente el compilador de c# no emite este opcode

Unaligned

Indica que una dirección que se encuentra actualmente encima de la pila de evaluación podría no estar alineada con el tamaño natural de los siguientes ldind, stind, ldfld, stfld, ldobj, stobj, initblk, o cpblk instrucción.

C# (y el CLR) hace bastantes garantías con respecto a la naturaleza alineada de gran parte de su código y datos resultantes. No es sorprendente que esto no se emita, pero puedo ver por qué se incluiría.

Unbox

Convierte la representación en caja de un tipo de valor a su forma sin caja.

El compilador de c# prefiere usar Unbox_Any instrucción exclusivamente para este fin. Me presume, basado en la adición de esto al conjunto de instrucciones en la versión 2.0 hace que los genéricos sean factibles o mucho más simples. En ese momento usarlo a lo largo del código para todo, genéricos o no, era más seguro, más simple o más rápido (o alguna combinación de todos).


Nota al pie:

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

Infraestructura. Esta es una reserva instrucción.

Estas no son instrucciones como tales, algunas instrucciones IL son más largas que otras. Estos de longitud variable deben comenzar con prefijos que nunca son válidos por sí mismos para que el análisis sea claro. Estos prefijos opcodes están reservados para eso, por lo que no se usan en ningún otro lugar. Sin duda, alguien que implementa un analizador basado en instrucciones switch para una secuencia IL apreciaría estos para poder atraparlos y mantener el estado.

 13
Author: ShuggyCoUk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-02 16:50:25

Un ejemplo interesante es tail.call (OpCodes.Tailcall ) que haría posible la optimización de Llamadas de cola para recursión.

 4
Author: Andrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-18 17:00:22

La directiva .override IL (no se si es el término correcto, pero ciertamente no es una instrucción ) es generada por el compilador de C#, pero solo en el caso especial de implementación de interfaz explícita.

Sería interesante poder usarlo más libremente, como en VB.NET, donde los miembros implementadores pueden ser alias o incluso tener un modificador de acceso diferente que el miembro de la interfaz.

 1
Author: Jordão,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-18 19:55:13