Язык программирования C#9 и платформа .NET5 - Джепикс Филипп - Страница 354
- Предыдущая
- 354/642
- Следующая
int32& refInt, class [System.Runtime.Extensions]System.Collections.ArrayList ar, [out] int32& outputInt) cil managed{ ...}Исследование кодов операций CIL
Последний аспект кода CIL, который будет здесь рассматриваться, связан с ролью разнообразных кодов операций. Вспомните, что код операции — это просто лексема CIL, используемая при построении логики реализации для заданного члена.
Все коды операций CIL (которых довольно много) могут быть разделены на три обширные категории:
• коды операций, которые управляют потоком выполнения программы ;
• коды операций, которые вычисляют выражения;
• коды операций, которые получают доступ к значениям в памяти (через параметры, локальные переменные и т.д.).
В табл. 19.4 описаны наиболее полезные коды операций, имеющие прямое отношение к логике реализации членов; они сгруппированы по функциональности.

Коды операций из следующей обширной категории (подмножество которых описано в табл. 19.5) применяются для загрузки (заталкивания) аргументов в виртуальный стек выполнения. Обратите внимание, что все эти ориентированные на загрузку коды операций имеют префикс
Id
В дополнение к набору кодов операций, связанных с загрузкой, CIL предоставляет многочисленные коды операций, которые явно извлекают из стека самое верхнее значение. Как было показано в нескольких начальных примерах, извлечение значения из стека обычно предусматривает его сохранение во временном локальном хранилище с целью дальнейшего использования (наподобие параметра для предстоящего вызова метода). Многие коды операций, извлекающие текущее значение из виртуального стека выполнения, снабжены префиксом
st
Имейте в виду, что различные коды операций CIL будут неявно извлекать значения из стека во время выполнения своих задач. Например, при вычитании одного числа из другого с применением кода операции
subsubДиректива .maxstack
При написании кода реализации методов на низкоуровневом языке CIL необходимо помнить о специальной директиве под названием
.maxstack.maxstack8.method public hidebysig instance void Speak() cil managed{<b> // Внутри области действия этого метода в стеке находится</b><b> // в точности одно значение (строковый литерал).</b><b> .maxstack 1</b> ldstr "Hello there..." call void [mscorlib]System.Console::WriteLine(string) ret}Объявление локальных переменных в CIL
Теперь давайте посмотрим, как объявлять локальные переменные. Предположим, что необходимо построить в CIL метод по имени
MyLocalVariables()voidSystem.StringSystem.Int32System.Objectpublic static void MyLocalVariables(){ string myStr = "CIL code is fun!"; int myInt = 33; object myObj = new object();}А вот как реализовать метод
MyLocalVariables().method public hidebysig static void MyLocalVariables() cil managed{ .maxstack 8<b> // Определить три локальные переменные.</b> .locals init (string myStr, int32 myInt, object myObj)<b> // Загрузить строку в виртуальный стек выполнения.</b> ldstr "CIL code is fun!"<b> // Извлечь текущее значение и сохранить его в локальной переменной [0].</b> stloc.0<b> // Загрузить константу типа i4 (сокращение для int32) со значением 33.</b> ldc.i4.s 33<b> // Извлечь текущее значение и сохранить его в локальной переменной [1].</b> stloc.1<b> // Создать новый объект и поместить его в стек.</b> newobj instance void [mscorlib]System.Object::.ctor()<b> // Извлечь текущее значение и сохранить его в локальной переменной [2].</b> stloc.2 ret- Предыдущая
- 354/642
- Следующая
