Таблица 15.6. Коды операций CIL для помещения данных в стек
| Код операции | Описание |
|---|---|
| ldarg (с множеством вариаций) | Помещает в стек аргумент метода. Вдобавок к общей операции ldarg (для которой требуется указать индекс, идентифицирующий аргумент), есть множество ее вариаций. Например, ldarg с числовым суффиксом (ldarg_0) используется для загрузки соответствующего аргумента. Другие вариации ldarg позволяют с помощью кодов констант CIL из табл. 15.4 указать конкретный тип загружаемых данных (например, ldarg_I4 для int32), а также тип данных и значение (ldarg_I4_5 для загрузки int32 со значением 5) |
| ldc (с множеством вариаций) | Помещает в стек значение константы |
| ldfld (с множеством вариаций) | Помещает в стек значение поля уровня экземпляра |
| ldloc (с множеством вариаций) | Помещает в стек значение локальной переменной |
| ldobj | Читает все значения объекта, размещенного в динамической памяти, и помещает их в стек |
| ldstr | Помещает в стек строковое значение |
Вдобавок к множеству специальных кодов операций загрузки, CIL предлагает набор кодов операций, которые непосредственно "выталкивают" из стека самое верхнее значение. Как продемонстрировали первые несколько примеров этой главы, удаление значения из стека обычно выполняется с целью последующего сохранения этого значения в локальной памяти для дальнейшего использования (например, в качестве параметра при последующем вызове метода). С учетом этого становится ясно, почему многие коды операций, связанные с удалением текущего значения из виртуального стека выполнения, имеют префикс st (store – сохранять). Соответствующие описания приведены в табл. 15.7.
Таблица 15.7. Коды операций для извлечения данных из cтека
| Код операции | Описание |
|---|---|
| pop | Удаляет значение, находящееся в настоящий момент на вершине стека, но не обеспечивает сохранение этого значения |
| starg | Сохраняет значение из вершины стека в аргументе метода с указанным индексом |
| stloc (c множеством вариаций) | Удаляет значение, находящееся на вершине стека, и запоминает это значение в переменной с указанным индексом из списка локальных переменных |
| stobj | Копирует значение указанного типа из стека в память по указанному адресу |
| stsfld | Заменяет значение статического поля значением из cтека |
Следует также знать о том, что различные коды операций CIL при выполнении своих задач
Директива .maxstack
При реализации метода непосредственно средствами CIL нужно помнить о специальной директиве, которая называется .maxstack. Как следует из ее названия, директива .maxstack задает максимальное число переменных, которые может вместить стек в любой момент времени при выполнении метода. К счастью, директива .maxstack имеет значение по умолчанию (8), которого оказывается достаточно для подавляющего большинства методов, создаваемых разработчиками. Но у вас также есть возможность определить это значение явно, чтобы при желании вручную указать числа локальных переменных в стеке.
.method public hidebysig instanсе void Speak cil managed {
// В контексте этого метода в стек помещается ровно
// одно значение (строковый литерал).
.maxstack 1
ldstr "Всем привет…"