Вспомните, что для управления прекращением потока выполнения, когда удовлетворено некоторое условие, используются коды операций br
br, bltn т.д.). В приведенном примере указано условие, согласно которому выполнение цикла for должно прекращаться, когда значение локальной переменной i становится больше или равно 10. С каждым проходом к значению i добавляется 1, после чего проверяемое условие оценивается заново.Также вспомните, что в случае применения любого кода операции CIL, предназначенного для ветвления, должна быть определена специфичная метка кода (или две), обозначающая место, куда будет произведен переход при истинном результате оценки условия. С учетом всего сказанного рассмотрим показанный ниже (отредактированный) код CIL, который сгенерирован утилитой ildasm.exe
.method public hidebysig static void CountToTen() cil managed
{
.maxstack 2
.locals init (int32 V_0, bool V_1)
IL_0000: ldc.i4.0 // Загрузить это значение в стек.
IL_0001: stloc.0 // Сохранить это значение по индексу 0.
IL_0002: br.s IL_000b // Перейти на метку IL_ 0008.
IL_0003: ldloc.0 // Загрузить значение переменной по индексу 0.
IL_0004: ldc.i4.1 // Загрузить значение 1 в стек.
IL_0005: add // Добавить текущее значение в стеке по индексу 0.
IL_0006: stloc.0
IL_0007: ldloc.0 // Загрузить значение по индексу 0.
IL_0008: ldc.i4.s 10 // Загрузить значение 10 в стек.
IL_0009: clt // Меньше значения в стеке?
IL_000a: stloc.1 // Сохранить результат по индексу 1.
IL_000b: ldloc.1 // Загрузить значение переменной по индексу 1.
IL_000c: brtrue.s IL_0002 // Если истинно, тогда перейти на метку IL 0002.
IL_000d: ret
}
Код CIL начинается с определения локальной переменной типа int32
IL_0008 и IL_0004, во время каждого из которых значение i увеличивается на 1 и проверяется на предмет того, что оно все еще меньше 10. Как только условие будет нарушено, осуществляется выход из метода.Заключительные слова о языке CIL
Ознакомившись с процессом создания исполняемого файла из файла *.il
*.il. Тем не менее, способность понимать код CIL может принести пользу, когда вам нужно исследовать сборку, для которой отсутствует исходный код.Существуют также коммерческие инструменты, которые восстанавливают исходный код сборки .NET Core. Если вам доводилось когда-либо пользоваться одним из инструментов подобного рода, то теперь вы знаете, каким образом они работают!
Динамические сборки
Естественно, процесс построения сложных приложений .NET Core на языке CIL будет довольно-таки неблагодарным трудом. С одной стороны, CIL является чрезвычайно выразительным языком программирования, который позволяет взаимодействовать со всеми программными конструкциями, разрешенными CTS. С другой стороны, написание низкоуровневого кода CIL утомительно, сопряжено с большими затратами времени и подвержено ошибкам. Хотя и правда, что знание — сила, вас может интересовать, насколько важно держать в уме все правила синтаксиса CIL. Ответ: зависит от ситуации. Разумеется, в большинстве случаев при программировании приложений .NET Core просматривать, редактировать или писать код CIL не потребуется. Однако знание основ языка CIL означает готовность перейти к исследованию мира динамических сборок (как противоположности статическим сборкам) и роли пространства имен System.Reflection.Emit