Суббота, 20.04.2024, 03:08
Приветствую Вас Гость | RSS | PDA

Всё для студента информата

Полезная информация

Статьи IT

Всё для студента IT » Статьи » Программирование для Microsoft® .NET

Общий промежуточный язык .NET Framework

Часто CIL называют псевдоассемблером, так как он определяет набор команд некоего процессора. Однако в данном случае процессором является не кусок кремния, а CLR. При написания программ для .NET Framework знать CIL нужно не более, чем ассемблер х8б для программирования под Windows. И все же элементарные познания в CIL могут быть полезны, если вам понадобится узнать, почему какой то метод FCL работает не так, как вы этого ожидали. У вас нет исходного кода FCL, но есть CIL.

CIL содержит примерно 100 команд. Некоторые из них — типичные низкоуровневые, аналогичные командам микропроцессоров, например, команды сложения двух значений (ADD) или перехода, если два значения равны (BEQ). Другие, более высокого уровня, редко встречаются в аппаратных наборах команд. Так, NEWOBJ создает экземпляр объекта, а THROW генерирует исключение. Благодаря такому богатству набора команд CIL, код на языке высокого уровня, таком как С# или Visual Basic .NET, зачастую порождает при компиляции удивительно малое число команд.

CIL использует стековую модель исполнения. Если процессоры х8б для обработки значений загружают их в регистры, то CLR помещает их в вычислительный стек. Чтобы сложить два числа, они копируются в стек, вызывается ADD, и результат считывается из стека. Копирование значения из памяти в стек называется загрузкой (loading), а копирование в обратном направлении — сохранением (storing).

В CIL есть несколько команд загрузки и сохранения. Например, LDLOC загружает в стек значение по некоторому адресу в памяти, a STLOC копирует значение из стека в память, удаляя его из стека.

В качестве примера работы CIL, рассмотрим фрагмент программы С#, в котором объявляются и инициализируются две переменные, затем они складываются, и сумма записывается в третью переменную:
int а = 3;
int b = 7;
int с = а + b;

Ниже приведен CIL, сгенерированный компилятором Microsoft C# (с моими комментариями):
Idc.i4.3 // Загрузить в стек 32-разрядное (14) число 3.
stloc.O // Сохранить его в локальной переменной 0 (а).
Idc.i4.7 // Загрузить на стек 32-разрядное (14) число 7,
stloc.1 // Сохранить его в локальной переменной 1 (Ь).
ldloc.0 // Загрузить в стек локальную переменную 0.
ldloc.1 // Загрузить в стек локальную переменную 1.
add // Сложить два числа и получить сумму в стеке.
stloc.2 // Сохранить сумму в локальной переменной 2 (с).

Как видите, CIL весьма прост. Однако непонятно, как выделяется память для локальных переменных a, b и с (для CLR это локальные переменные О, 1 и 2). С помощью метаданных. При компиляции в метаданные метода помещаются сведения о том, что объявлены три локальных 32-разрядных целых переменных. CLR считывает эти сведения и выделает память для локальных переменных перед началом исполнения метода. Если дизассемблировать метод с помощью ILDASM, метаданные будут отображены как директива компилятора;

.locals init (int32 V_0, // Локальная переменная 0 (а).
int32 \М, // Локальная переменная 1 (Ь).
int32 V_2) // Локальная переменная 2 (с).

Это превосходный пример того, как важны метаданные для CLR. Они служат не только для проверки безопасности типов, но и для подготовки контекста исполнения. Кстати, если исполняемый модуль С# скомпилирован с ключом /DEBUG, то ILDASM отобразит настоящие названия переменных вместо условных обозначений вроде V_0.

В .NET Framework SDK есть документ, описывающий весь набор команд CIL в
мельчайших подробностях. Не буду помещать здесь полный список команд CIL —
приведу лишь наиболее часто используемые команды и их краткое описание.

Распространенные команды CIL
Команда Описание
BOX Преобразует размерный тип в ссылочный.
CALL Вызывает метод; если метод виртуальный, то виртуальность игнорируется.
CALLVIRT Вызывает метод; если метод виртуальный, виртуальность учитывается.
CASTCLASS Приводит объект к другому типу.
LDC Загружает в стек числовую константу.
LDARGJA] Загружает в стек аргумент или его адрес [А] .
LDELEM Загружает в стек элемент массива,
LDLOCfA] Загружает в стек локальную переменную или ее адрес [А],
LDSTR Загружает в стек строковый литерал.
NEWARK Создает новый массив.
NEWOBJ Создает новый объект.
RET Выполняет возврат из метода.
STARG Копирует в аргумент значение из стека,
STELEM Копирует значение из стека в элемент массива.
STLOC Перемещает значение из стека в локальную переменную,
THROW Генерирует исключение.
UNBOX Преобразует ссылочный тип в размерный.

ILDASM, которая позволяет посмотреть метаданные, является и прекрасным
дизассемблером CIL Запустите ILDASM и откройте с ее помощью одну из библиотек
System.'.dll в каталоге \%SystemRoot%\Microsoft.NET\Framcwork\vl.0.w«nw. Эти DLL
относятся к библиотеке классов .NET Framework. Затем выберите какой-нибудь метод для дизассемблирования. Методы легко отыскать — они обозначены малиновыми прямоугольниками. Дважды щелкнув метод, вы увидите его CIL вместе с директивами компилятора, сгенерированными по метаданным метода. Более того, ILDASM — это двунаправленный дизассемблер, т. е. ему на вход можно подать дезассемблированный код и снова получить CIL.

Разработчики часто поднимают проблему интеллектуальной собственности:
если каждый может дизассемблировать FCL, что помешает конкуренту дизассемблировать чужой продукт? Восстановление исходного текста по CIL — нетривиальная задача, но это проще, чем восстановить его по коду х8б. Кроме того, декомпиляторы, генерирующие по CIL исходный текст на С#, имеются в свободном доступе в Интернете. Как же защитить свою интеллектуальную собственность?

Короткий ответ — по обстоятельствам. Код, исполняемый только на серверах, например, Web-сервисы XML, недоступен пользователям и, таким образом, не может быть дизассемблирован, если только кто-нибудь не проникнет сквозь ваш брандмауэр. Код, поставляемый конечным пользователям, может быть зашифрован утилитами, поставляемыми третьими фирмами. Такие утилиты не гарантируют того, что никто не сможет прочитать ваш код, но значительно затрудняют это. В конце концов, если у кого-то есть физический доступ к вашему CIL и большое желание вскрыть его, он это все равно сделает. В утешение можно сказать, что Java-программисты борются с этой проблемой годами, Здесь нет совершенного решения, кроме размещения всего кода приложения на сервере.

Похожие статьи:

Не нашли то, что Вам нужно?.. Найдите ответ на форуме!
Категория: Программирование для Microsoft® .NET | Добавил: Akron (12.02.2012)
Просмотров: 356 | Теги: .NET
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Сообщество
Помощь
Форма входа
Поиск

Студенческий помощник по информатике © 2024
При цитировании материалов данного сайта, обязательна ссылка на источник: ITstudents.ru



>