Usted está en la dirección correcta para deshacerse de los "nop" s:
Cuando proporciona un argumento adicional para una llamada de Emitir, siempre asegúrese de comprobar en MSDN el tipo de argumento adecuado.
Para OpCodes.Ldc_I4_S, MSDN afirma:
ldc.i4.s es una codificación más eficiente para empujar los números enteros de -128 a 127 en la> pila de evaluación.
La siguiente sobrecarga del método Emit puede utilizar el código de operación ldc.i4.s:
ILGenerator.Emit (código de operación, byte)
Así que la segunda parte de su código tendrá resultados impredecibles (además de esos fastidiosos nop) en tiempo de ejecución, ya que está intentando cargar un "int8" en la pila, pero proporcionando un valor "int32" o "corto":
else if (IsBetween(value, short.MinValue, short.MaxValue))
{
gen.Emit(OpCodes.Ldc_I4_S, (short)value);
}
else
{
gen.Emit(OpCodes.Ldc_I4_S, value);
}
Debe usar Ldc_I4 en lugar de Ldc_I4_S si desea cargar correctamente un int32/short (o algo de mayor magnitud que un byte) en la pila. lo que el código debería tener este aspecto en lugar de la muestra anterior:
else
{
gen.Emit(OpCodes.Ldc_I4, value);
}
Esta es una suposición, pero los tres de nop que se generaron probable que tenga algo que ver con los bytes adicionales de su int32
Espero que ayude ...
¿Quizás está empaquetando las instrucciones en un bloque de cierto tamaño y llenando el resto con nops? – Joe
Como el NOP no causa ningún daño, ¿por qué desea deshacerse de ellos? – RichardOD
Si no sirven, por qué tenerlos allí, el código C# resultante no tiene ninguno ... – Peter