Открыть сервис

Common Intermediate Language

Common Intermediate Language (CIL, ранее назывался Microsoft Intermediate Language, MSIL) — это промежуточный язык программирования низкого уровня, разработанный компанией Microsoft в рамках платформы .NET Framework. CIL является объектом спецификации Common Language Infrastructure (CLI), принятой в качестве международного стандарта ISO/IEC 23271. Он представляет собой набор инструкций, не зависящих от конкретной архитектуры процессора, и служит связующим звеном между исходным кодом на языках высокого уровня (C#, Visual Basic .NET, F# и других) и машинным кодом, исполняемым на целевой платформе.

История

Разработка CIL началась в конце 1990-х годов в рамках проекта Microsoft по созданию новой платформы для разработки приложений, которая должна была объединить лучшие черты COM и Java. Первоначально язык назывался Microsoft Intermediate Language (MSIL). В 2000 году Microsoft представила спецификацию .NET Framework, а в 2001 году — первую версию платформы. В 2002 году спецификация CLI была передана в организацию Ecma International для стандартизации, а в 2005 году — в ISO. В процессе стандартизации язык получил официальное название Common Intermediate Language. CIL стал основой для выполнения кода в среде Common Language Runtime (CLR) — виртуальной машине, обеспечивающей управление памятью, безопасность типов и сборку мусора.

Архитектура и принципы работы

Компиляция в CIL

Исходный код, написанный на одном из языков платформы .NET, сначала компилируется в сборку (assembly), содержащую код на CIL и метаданные. Метаданные описывают типы, методы, свойства и другие элементы, определённые в сборке, а также ссылки на внешние сборки. Этот процесс выполняется компилятором соответствующего языка (например, csc.exe для C# или vbc.exe для Visual Basic .NET).

JIT-компиляция

При запуске приложения код на CIL не выполняется напрямую. Вместо этого CLR использует Just-In-Time (JIT) компилятор, который преобразует инструкции CIL в машинный код, специфичный для архитектуры процессора (x86, x64, ARM и т. д.). JIT-компиляция происходит по мере необходимости: метод компилируется только при первом вызове. Результат компиляции кэшируется в памяти для повторного использования. Это позволяет сочетать переносимость кода с производительностью, близкой к нативному исполнению.

NGen и Ahead-of-Time компиляция

Для ускорения запуска приложений Microsoft предоставляет утилиту NGen (Native Image Generator), которая выполняет Ahead-of-Time (AOT) компиляцию CIL-кода в машинный код во время установки приложения. Сгенерированные образы сохраняются в кэше сборок и используются CLR вместо JIT-компиляции. В более поздних версиях .NET (начиная с .NET Core) появился механизм ReadyToRun (R2R), который также выполняет AOT-компиляцию, но с меньшей степенью оптимизации, оставляя возможность для JIT-компиляции горячих участков кода.

Инструкции CIL

CIL является объектно-ориентированным языком с поддержкой типов значений и ссылочных типов. Набор инструкций CIL включает около 200 команд, разделённых на несколько категорий:

Арифметические и логические инструкции

  • add, sub, mul, div — арифметические операции.
  • and, or, xor, not — побитовые операции.
  • ceq, cgt, clt — операции сравнения.

Инструкции управления потоком

  • br, brtrue, brfalse — безусловный и условные переходы.
  • call, callvirt — вызов методов (статических и виртуальных).
  • ret — возврат из метода.
  • switch — реализация оператора выбора.

Инструкции работы с объектами и памятью

  • newobj — создание нового объекта.
  • ldfld, stfld — чтение и запись полей объекта.
  • ldarg, stargработа с аргументами метода.
  • ldloc, stloc — работа с локальными переменными.
  • box, unboxупаковка и распаковка типов значений.

Инструкции для работы с массивами

  • newarr — создание массива.
  • ldelem, stelem — чтение и запись элементов массива.
  • ldlen — получение длины массива.

Инструкции для исключений

  • throw — генерация исключения.
  • leave — выход из блока обработки исключений.

Метаданные

Метаданные являются неотъемлемой частью сборки .NET. Они хранят информацию о всех типах, определённых в сборке, их членах (полях, методах, свойствах, событиях), а также о ссылках на другие сборки. Метаданные позволяют CLR выполнять проверку безопасности типов, разрешать вызовы методов и управлять временем жизни объектов. Благодаря метаданным, код на CIL является самодокументируемым: для его использования не требуются отдельные заголовочные файлы или IDL-описания.

Преимущества и недостатки

Преимущества

  • Переносимость: код на CIL может выполняться на любой платформе, для которой реализована среда CLR (Windows, Linux, macOS, Android, iOS и другие).
  • Безопасность типов: CLR проверяет корректность операций с типами во время выполнения, что снижает риск ошибок, связанных с памятью.
  • Управление памятью: сборщик мусора автоматически освобождает неиспользуемую память, что упрощает разработку.
  • Многоязыковая поддержка: код на разных языках (C#, VB.NET, F#, C++/CLI) может быть скомпилирован в CIL и взаимодействовать друг с другом.

Недостатки

  • Производительность: JIT-компиляция добавляет накладные расходы при первом запуске приложения, хотя последующие вызовы выполняются с машинной скоростью.
  • Сложность обратной разработки: код на CIL легче поддаётся декомпиляции, чем нативный машинный код, что требует использования обфускаторов для защиты интеллектуальной собственности.
  • Зависимость от среды выполнения: для работы приложения необходима установленная среда CLR (или .NET Runtime), что может быть неудобно для некоторых сценариев.

Применение

CIL является основой для всех приложений, разработанных на платформе .NET, включая:

  • Десктопные приложения для Windows (Windows Forms, WPF).
  • Веб-приложения (ASP.NET, ASP.NET Core).
  • Мобильные приложения (Xamarin, .NET MAUI).
  • Игровые приложения (Unity использует CIL для скриптов на C#).
  • Облачные сервисы и микросервисы (Azure Functions, .NET Core).
  • Библиотеки классов и компоненты многократного использования.

Инструменты для работы с CIL

  • IL Disassembler (ildasm.exe): утилита, входящая в состав Windows SDK, позволяющая просматривать код на CIL и метаданные сборки.
  • IL Assembler (ilasm.exe): утилита для компиляции кода на CIL в сборку.
  • dnSpy: сторонний декомпилятор и отладчик, позволяющий редактировать код на CIL непосредственно в сборке.
  • Mono.Cecil: библиотека для чтения, модификации и создания сборок .NET программным способом.

Интересные факты

  • CIL является строго типизированным языком: все инструкции работают с определёнными типами данных, и CLR проверяет соответствие типов во время выполнения.
  • Некоторые инструкции CIL, такие как ldnull (загрузка нулевой ссылки) и dup (дублирование значения на стеке), не имеют прямых аналогов в языках высокого уровня.
  • В спецификации CLI определены не только инструкции CIL, но и система типов CTS (Common Type System), которая обеспечивает единообразие типов для всех языков платформы .NET.
  • CIL поддерживает обобщённые типы (generics) на уровне инструкций, что позволяет создавать эффективные обобщённые структуры данных без необходимости в упаковке типов значений.

Источники

  1. ISO/IEC 23271:2012 — Information technology — Common Language Infrastructure (CLI).
  2. ECMA-335 — Common Language Infrastructure (CLI) Specification.
  3. Microsoft .NET Framework Documentation — Common Intermediate Language (CIL) Instruction Set.
  4. Richter, Jeffrey. CLR via C#. — 4th ed. — Microsoft Press, 2012.
  5. Albahari, Joseph; Albahari, Ben. C# 10 in a Nutshell. — O'Reilly Media, 2022.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →