Допустим, следующая CIL-программа:
.assembly extern mscorlib {}
.assembly Program {}
.method private static void Main() cil managed
{
.entrypoint
.maxstack 4
.locals init ( int32[] a,
uint32 t )
// Creates an array of int of size 10
ldc.i4 10
newarr int32
stloc.0
// Writes 0xaabbccdd at the index 2 of the array
ldloc.0
ldc.i4.2
ldc.i4 0xaabbccdd
stelem.i4
// Loads
ldloc.0
ldc.i4 9 // <HERE>
ldelem.i1
stloc.1
ldstr "Value: 0x{0:x8}"
ldloc.1
box [mscorlib]System.UInt32
call void [mscorlib]System.Console::WriteLine(string, object)
ret
}
Эта программа:
- создает массив типа int 10
- записывает 0xaabbccdd в индекс 2 массива
- пытается прочитать один байт в массиве, используя ldelem.i1
- печатает результат
Хитрость в том, что я использую «ldelem.i1» вместо более стандартного «idelem.i4» для проблем с производительностью (я хочу избежать маскирования). Идея состоит в том, чтобы получить доступ к данным массива так, как это делается с указателями в к.
Но все не так хорошо, потому что программа аварийно завершает работу (IndexOutOfRangeException) для индексов более 10 в качестве аргумента для ldelem.i1.
Это делает трюк бесполезным, так как я не могу получить доступ к данным после первой половины целого числа в третьем индексе.
В идеале я хочу получить доступ к байтам до индекса 39, что соответствует последнему байту целого числа в индексе 9.
Я был бы очень признателен, если бы у кого-то были идеи на этот счет.