2010-04-27 4 views
3

Я думаю, что, возможно, мне не хватает чего-то важного, но я не могу понять, как построить условный оператор в IL с помощью динамического метода. Раньше я только слегка баловался, но сейчас мне нужно расширить код.Блок 'if' в IL

Есть ли какая-то документация где-то, что я не нашел (кроме документации CLI), или у кого-то есть пример кода? Это было бы фантастически.

Приветствия,

+1

Что вы подразумеваете под «динамическим методом»? Оператор if в сборке - это, как правило, операция перехода. Ищите команду IL, которая аналогична –

+0

ОК, я буду. По «динамическому методу» я имею в виду, например: DynamicMethod dm = new DynamicMethod («... –

ответ

4

В зависимости от конкретной кода, различные инструкции ветвления вашего друга.

Вот

if(memory[pointer] > 0) goto IL_0002; 

в IL:

IL_001f: ldsfld  uint8[] BFHelloWorldCSharp.Program::memory 
IL_0024: ldsfld  int16 BFHelloWorldCSharp.Program::pointer 
IL_0029: ldelem.u1 
IL_002a: ldc.i4.0 
IL_002b: bgt  IL_0002 

Вы в основном раздвинуть значения, которые вы хотите сравнить в стек, а затем вызвать bgt прыгать, где вам нужно.

Вы можете проверить OpCodes Class для быстрого обзора команд IL, например brtrue/brfalse или beq.

Я бы также рекомендовал записать команду if в C#, скомпилировать ее и использовать ILDASM или Reflector для поиска сгенерированного ИЛ.

+0

Спасибо за эту ссылку на класс OpCodes - я не смог найти ссылку на ссылку с любого из emit articles ... annoying! –

+0

@ Luke Если вам интересно, я начал серию о написании компилятора .net (я выбрал brainf..k как язык из-за его простоты). Я не использую Динамический метод, но я использую Reflection.Emit. Статья о написании компилятора (часть 6) должна появиться в выходные дни: http://www.stum.de/tag/brainfk/ –

+0

@Luke Исходный код для моего компилятора находится здесь: http://pastie.org/910946 - Это утверждение какое-то время, хотя и ведет себя аналогично. Может быть, это помогает. –

1

Вот как это происходит:

Определить метку, например:

var skipProperty = il.DefineLabel(); 

называют ваше состояние:

il.Emit(OpCodes.Brtrue, skipProperty); 

в том месте, где вы хотите, чтобы пропустить (например, конец if):

il.MarkLabel(skipProperty); 

Итак, вы создаете ярлык (сначала вам нужно сделать так, чтобы ссылка существовала, вы называете «метку» позже, чтобы поместить метку в фактическое место в коде, который вы хотите). OpCodes.Brtrue является лишь одним из многих условных операций, перечисленных в статье link text (спасибо Michael

Смежные вопросы