public static void MyMethod(int inputInt, ref int refInt, ArrayList ar, out int outputInt) {
outputInt = 0; // Просто чтобы удовлетворить компилятор C#…
}
Если спроецировать этот метод в CIL-код, вы обнаружите, что ссылки на параметры C# будут обозначены знаком амперсанда (&), добавленного в виде суффикса к типу данных, соответствующему параметру (int32&). Для выходных параметров тоже используется суффикс &, но, кроме того, они обозначены маркером CIL [out], Также обратите внимание на то, что в том случае, когда параметр является ссылочным типом (как тип [mscorlib]System.Collections.ArrayList в нашем примере), ему предшествует лексема class (не путайте с директивой .class!).
.method public hidebysig static void MyMethod(int32 inputInt, int32& refInt, class [mscorlib]System.Collections.ArrayList ar, [out] int32& outputInt) cil managed {
…
}
Анализ кодов операций CIL
Заключительной темой нашего обсуждения в этой главе в отношении программного кода CIL будет роль кодов операций. Напомним, что код операции – это просто лексема CIL, используемая для построения логики реализации данного члена. Полный набор кодов операций CIL (который сам по себе довольно велик) можно разбить на следующие большие категории.
• Коды операций для управления программой
• Коды операций для оценки выражений
• Коды операций для осуществления доступа к значениям в памяти (через параметры, локальные переменный и т.п.)
Чтобы продемонстрировать некоторые возможности реализации членов средствами CIL, в табл. 15.5 предлагаются описания некоторых из наиболее часто используемых кодов операций, непосредственно связанных с логикой реализации членов. Кроме того, коды операций в данной таблице сгруппированы по функциональности.
Таблица 15.5. Коды операций CIL, связанные с реализацией членов
| Коды операций | Описание |
|---|---|
| add, sub, mul, div, rem | Позволяют выполнять сложение, вычитание, умножение и деление для пар значений (rem возвращает остаток от деления) |
| and, or, not, xor | Позволяют выполнять соответствующие бинарные операции для пар значений |
| ceq, cgt, clt | Позволяют сравнивать пару значений из стека различными способами, например: ceq: сравнение в отношении равенства cgt: сравнение в отношении "больше" clt: сравнение в отношении "меньше" |
| box, unbox | Используются для конвертирования ссылочных типов и типов, характеризуемых значениями |
| ret | Используется для выхода из метода и (если это необходимо) возвращения значения вызывающей стороне |
| beq, bgt, ble, blt, switch | Используются (в дополнение к множеству других родственных кодов операций) для управления логикой ветвления в методах, например: beq: переход к заданной метке, если выполняется равенство bgt: переход к заданной метке, если больше ble: переход к заданной метке, если меньше или равно blt: переход к заданной метке, если меньше Все коды операций, связанные с ветвлением, требуют указания метки CIL-кода, по которой должен осуществляться переход в том случае, когда соответствующее сравнение возвращает true |
| call | Используется для вызова члена указанного типа |
| newarr, newobj | Позволяет разместить в памяти новый массив или новый объект (cоответственно) |
Следующая большая категория кодов операций CIL (подмножество которой показано в табл. 15.6) используется для загрузки аргументов в виртуальный стек выполнения. Обратите внимание на то, что эти относящиеся к загрузке коды операций имеют префикс ld (load – загрузка).