Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 39 стр.

UptoLike

нейшем, генерация метаданных даже для такого несложного примера тре-
бует больших усилий. Сборку .NET, соответствующую нашему примеру,
можно получить, если откомпилировать следующую программу, записан-
ную в синтаксисе ассемблера ILASM:
.assembly HelloWorld
{
.hash algorithm 0x00008004
.ver 1:0:1:1
}
.module HelloWorld.exe
// hello() – единственный метод в нашей сборке
.method public static void hello() cil managed
{
.entrypoint
.maxstack 8
// Загружаем строку “Hello, World!” на стек
ldstr “Hello, World!”
// Выводим строку на экран
call void [mscorlib]System.Console::WriteLine(string)
// Ожидаем, пока пользователь введет строку
call string [mscorlib]System.Console::ReadLine()
// Выводим введенную строку на экран
call void [mscorlib]System.Console::WriteLine(string)
// Завершаем выполнение
ret
}
2.2.1. Расположение метаданных и кода внутри сборки
В предыдущем разделе данной главы мы рассмотрели формат испол-
няемых файлов .NET и выяснили, что он дает разработчику достаточно
большую свободу для размещения отдельных элементов внутри исполня-
емого файла. В частности, исполняемые файлы могут содержать несколь-
ко секций, и расположение этих секций, а также данных внутри них явля-
ется более или менее произвольным.
Давайте выберем для нашего учебного примера схему размещения
данных внутри исполняемого файла, изображенную на рисунке 2.7. Мы
будем использовать две секции: секция «.text» будет содержать всю основ-
ную информацию, а в секции «.reloc» будет размещена таблица релокаций.
Структура программных компонентов
65
0x00, 0x00, 0x0A, 0x28, 0x01, 0x00, 0x00, 0x0A,
0x28, 0x02, 0x00, 0x00, 0x0A, 0x2A
};
2.1.6.6. Пример работы программы
Итак, попробуем запустить нашу программу, набрав в консоли
pegen.exe (так будет называться наша программа):
C:\>Pegen.exe
Если все прошло успешно, то на экране мы увидим сообщение об ус-
пешной генерации сборки hello.exe:
File: hello.exe generated
Запустим сгенерированную сборку:
C:\>hello.exe
Программа распечатает на экране строку «Hello» и попросит ввести
произвольный текст. Введем, например, строку:
Hello Programm
В результате программа распечатает на экране строку, введенную ра-
нее, и закончит свою работу:
Hello Programm
2.2. Формат метаданных
Метаданные служат для описания типов, находящихся в сборке
.NET, и хранятся в исполняемых файлах. Для хранения метаданных ис-
пользуется достаточно сложный двоичный формат, изложение которого
заняло бы слишком много времени, поэтому в этом разделе мы ограни-
чимся лишь частичным и в большой степени поверхностным описанием
формата метаданных.
Если поставить себе цель в двух словах охарактеризовать формат мета-
данных в сборках .NET, то можно сказать следующее: он был бы значитель-
но проще, если бы его разработчики не уделяли чрезмерного внимания во-
просу компактности хранения метаданных. Дело в том, что спецификация
формата определяет по нескольку способов кодирования одной и той же
информации, описывает способы сжатия отдельных элементов метаданных
(например, сигнатур методов) и, тем самым, оказывается загроможденной
множеством деталей, затрудняющим разработку метаинструментов.
Для того чтобы провести обзор формата метаданных в этом разделе,
мы используем следующий прием: рассмотрим только те детали формата,
которые используются в незатейливом примере, выводящем на экран над-
пись «Hello, World!», а затем ожидающим ввода данных с клавиатуры. Мо-
жет показаться, что пример слишком прост, однако, как мы увидим в даль-
64
CIL и системное программирование в Microsoft .NET
64                            CIL и системное программирование в Microsoft .NET   Структура программных компонентов                                     65


          0x00, 0x00, 0x0A, 0x28, 0x01, 0x00, 0x00, 0x0A,                         нейшем, генерация метаданных даже для такого несложного примера тре-
          0x28, 0x02, 0x00, 0x00, 0x0A, 0x2A                                      бует больших усилий. Сборку .NET, соответствующую нашему примеру,
     };                                                                           можно получить, если откомпилировать следующую программу, записан-
                                                                                  ную в синтаксисе ассемблера ILASM:
2.1.6.6. Пример работы программы                                                       .assembly HelloWorld
     Итак, попробуем запустить нашу программу, набрав в консоли                        {
pegen.exe (так будет называться наша программа):                                       .hash algorithm 0x00008004
        C:\>Pegen.exe                                                                  .ver 1:0:1:1
     Если все прошло успешно, то на экране мы увидим сообщение об ус-                  }
пешной генерации сборки hello.exe:                                                     .module HelloWorld.exe
        File: hello.exe generated                                                      // hello() – единственный метод в нашей сборке
     Запустим сгенерированную сборку:                                                  .method public static void hello() cil managed
        C:\>hello.exe                                                                  {
     Программа распечатает на экране строку «Hello» и попросит ввести                  .entrypoint
произвольный текст. Введем, например, строку:                                          .maxstack 8
        Hello Programm                                                                 // Загружаем строку “Hello, World!” на стек
     В результате программа распечатает на экране строку, введенную ра-                ldstr “Hello, World!”
нее, и закончит свою работу:
        Hello Programm                                                                 // Выводим строку на экран
                                                                                       call void [mscorlib]System.Console::WriteLine(string)

2.2. Формат метаданных                                                                 // Ожидаем, пока пользователь введет строку
                                                                                       call string [mscorlib]System.Console::ReadLine()
     Метаданные служат для описания типов, находящихся в сборке
.NET, и хранятся в исполняемых файлах. Для хранения метаданных ис-                     // Выводим введенную строку на экран
пользуется достаточно сложный двоичный формат, изложение которого                      call void [mscorlib]System.Console::WriteLine(string)
заняло бы слишком много времени, поэтому в этом разделе мы ограни-
чимся лишь частичным и в большой степени поверхностным описанием                       // Завершаем выполнение
формата метаданных.                                                                    ret
     Если поставить себе цель в двух словах охарактеризовать формат мета-              }
данных в сборках .NET, то можно сказать следующее: он был бы значитель-
но проще, если бы его разработчики не уделяли чрезмерного внимания во-
                                                                                  2.2.1. Расположение метаданных и кода внутри сборки
просу компактности хранения метаданных. Дело в том, что спецификация                   В предыдущем разделе данной главы мы рассмотрели формат испол-
формата определяет по нескольку способов кодирования одной и той же               няемых файлов .NET и выяснили, что он дает разработчику достаточно
информации, описывает способы сжатия отдельных элементов метаданных               большую свободу для размещения отдельных элементов внутри исполня-
(например, сигнатур методов) и, тем самым, оказывается загроможденной             емого файла. В частности, исполняемые файлы могут содержать несколь-
множеством деталей, затрудняющим разработку метаинструментов.                     ко секций, и расположение этих секций, а также данных внутри них явля-
     Для того чтобы провести обзор формата метаданных в этом разделе,             ется более или менее произвольным.
мы используем следующий прием: рассмотрим только те детали формата,                    Давайте выберем для нашего учебного примера схему размещения
которые используются в незатейливом примере, выводящем на экран над-              данных внутри исполняемого файла, изображенную на рисунке 2.7. Мы
пись «Hello, World!», а затем ожидающим ввода данных с клавиатуры. Мо-            будем использовать две секции: секция «.text» будет содержать всю основ-
жет показаться, что пример слишком прост, однако, как мы увидим в даль-           ную информацию, а в секции «.reloc» будет размещена таблица релокаций.