Шрифт:
Во-первых, обратите внимание на то, что файл *.il начинается с объявления всех внешних компоновочных блоков, на которые ссылается данный компоновочный блок. Здесь вы видите только одну директиву .assembly extern для одного обязательно присутствующего mscorlib.dll. Если бы ваша библиотека классов использовала типы из других внешних компоновочных блоков, вы бы обнаружили дополнительные директивы .assembly extern.
Далее следует формальное определение вашего компоновочного блока HelloProgram.exe, для которого указана версия 0.0.0.0, назначаемая по умолчанию (если вы не укажете иное значение с помощью атрибута [AssemblyVersion]). После этого приводятся другие описания компоновочного блока, для которых используются другие директивы CIL (такие, как .module, .imagebase и т.д.).
После указания ссылок на внешние компоновочные блоки и определения текущего компоновочного блока идет определение типа Program. Обратите внимание на то, что директива.class имеет несколько атрибутов (многие из которых необязательны), – например, атрибут extends, задающий базовый класс типа.
Большой кусок программного кода CIL соответствует конструктору класса, заданному по умолчанию, и методу Main. Оба они определены (в частности) с помощью директивы .method. После определения этих членов с помощью подходящих директив и атрибутов они реализуются с помощью различных кодов операций.
Важно понять, что в CIL при взаимодействии с типами .NET (например, с System.Console) всегда необходимо использовать абсолютные имена типов. Более того, к абсолютному имени типа всегда должен добавляться (в квадратных скобках) префикс с понятным именем компоновочного блока, определяющего этот тип. Взгляните на CIL-реализацию Main.
Реализация конструктора, заданного по умолчанию, в терминах программного кода CIL включает еще одну относящуюся к загрузке инструкцию (ldarg.0). В данном случае значение загружается в стек не как пользовательская переменная, указанная нами, а как текущая объектная ссылка (подробности этого процесса будут описаны позже). Также обратите внимание на то, что конструктор, заданный по умолчанию, явно вызывает конструктор базового класса.
Роль меток в программном коде CIL
Вы. конечно, заметили, что в каждой строке программного кода реализации содержится префикс в форме лексемы IL_XXX: (например, IL_0000: IL_0001: и т.д.). Эти лексемы называются метками кода, и они могут иметь любой вид, какой вы только пожелаете (лишь бы они не дублировались в пределах одного и того же контекста). При записи содержимого компоновочного блока в файл с помощью ildasm.exe автоматически генерируются метки кода, имеющие вид IL_XXX:. Но вы можете изменить их с тем, чтобы они стали более информативными.