01. Первая программа на IL

Занятие 1. Первая программа на IL #

Для создания своей первой программы мы должны соблюсти всего два требования:

  1. Включить в программу объявление сборки (assembly)
  2. Объявить метод, который будет являться точкой входа в программу Однако чтобы наша программа делал хоть что-то полезное :), мы добавим в нее вывод незабвенной строки «Привет, мир!». Итак, код нашей программы:
.assembly Step_1 {}
.assembly extern mscorlib {}

.method static void main()
{
	.entrypoint
	.maxstack 1
	
	ldstr "Привет, мир!"
	call void [mscorlib]System.Console::WriteLine(string)
	
	ret
}

Давайте разберем его подробно.

Сначала мы описываем сборку, которая будет состоять всего лишь из одного нашего файла (в .Net поддерживаются сборки, которые могут состоять из нескольких файлов-модулей, однако на практике такие сборки встречаются не очень часто, и нам они не понадобятся).

Для описания сборки используется директива .assembly, за которой следует имя сборки и фигурные скобки. В этих скобках могут указываться дополнительные параметры сборки (например, культура или номер версии), но для простоты мы их опускаем.

Затем следует директива .assembly extern. Эта директива указывает внешние сборки (библиотеки), к которым будет происходить обращение из нашего кода. В фигурных скобках также могут указываться дополнительные параметры, уточняющие какую именно сборку нужно подключать (в частности, там указываются параметры строго имени сборки – версия, хэш-сумма, публичный ключ, культура).

Следует иметь в виду, что компилятор ilasm.exe от Microsoft всегда добавляет ссылку на mscorlib в любую компилируемую сборку, т.е. строка .assembly extern mscorlib {} является излишней. Однако, такое поведение характерно только для данного компилятора.

После объявления имени сборки и ее внешних зависимостей следует объявление метода, единственного в нашей программе. Для объявления методов используется директива .method. В нашем случае она объявляет метод main, который:

  • является статическим (т.е. для вызова он не требует наличия экземпляра объекта). Это указывается атрибутом static;
  • не возвращает значений. Указывается типом возвращаемого значения void;
  • не имеет параметров.

Для тех, кто привык к языку C#, может показаться непривычным, что метод объявляется без указания класса. Однако исполнимая среда .Net и язык IL поддерживает объявление методов вне какого-либо типа.

Тело метода main заключается в фигурные скобки.

В самом начале метода стоит еще две директивы:

  • .entrypoint – указывает, что данный метод является точкой входа в программу (т.е. именно с него начнется выполнение). В отличие от C# имя первой выполняемой процедуры для .Net не важно, и может быть любым
  • .maxstack – указывает сколько нужно выделить слотов (ячеек) в стеке нужд данного метода. В нашем случае указан 1 слот (т.к. больше в нашей программе и не нужно)

Затем следуют три команды языка IL:

  • ldstr – загружает в стек (вот и пригодился 1 слот) указатель на строковую константу. Ее операнд – сама константа;
  • call – вызывает метод. В качестве операнда этой команде передается описатель метода, который нужно вызвать. В нашем случае вызывается статический метод WriteLine, который объявлен в классе System.Console, в сборке mscorlib. Очень важный момент: в классе System.Console имеется множество перегруженных методов WriteLine, которые отличаются набором передаваемых им параметров (иначе говоря, сигнатурой), поэтому при описании метода перечисляются типы всех его параметров! В нашем случае используется метод с единственным параметром типа string.
  • ret – инструкция которая завершает работу текущего метода и возвращает управление вызвавшему методу. Т.к. наш метод является точкой входа в программу, вызов этой инструкции, по сути, приведет к выходу из программы.

Вот и вся наша программа.

Чтобы скомпилировать ее достаточно вызвать команду:

<путь к папке .Net Framework>\ilasm.exe <имя файла с программой>

Например, вот так:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe step_1.il

В результате (если ничего не напутать при наборе и не указывать других параметров), то получится исполнимый файл step_1.exe, который делает все, что мы в него закладывали!

Задание #

  1. Скопируйте, скомпилируйте и запустите предложенную программу