Язык CIL, в отличие от большинства других ассемблерных языков, содержит богатый набор инструкций, предназначенных для поддержки объектной модели. Этот набор можно разделить на четыре основные категории:
Инструкции для работы с объектами - это базовые инструкции для поддержки объектно-ориентированной парадигмы.
Инструкция newobj (см. таблицу 3.25) выполняет выделение памяти для объекта в куче и затем вызывает для этого объекта конструктор. Операции выделения памяти и вызова конструктора объединены в одной инструкции не случайно, так как это гарантирует отсутствие в куче неинициализированных объектов.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x73 | newobj |
token |
Создает новый объект и вызывает для него конструктор |
Диаграмма стека для инструкции newobj:
... , arg1, ... , argN -> ... , obj
Инструкция newobj потребляет со стека вычислений параметры конструктора и оставляет на стеке ссылку на созданный объект. Параметры вызываемого конструктора должны быть расположены в стеке слева направо, то есть сначала на стек должен быть загружен первый аргумент, затем второй и т.д.
Хотя первым (неявным) параметром для любого конструктора является ссылка на инициализируемый объект (параметр this ), перед вызовом инструкции newobj этот параметр не должен загружаться на стек вычислений. Дело в том, что ссылка на объект формируется в процессе выполнения инструкции (после выделения памяти в куче и до вызова конструктора) и затем автоматически передается конструктору. Происходит как бы "подкладывание" ссылки this под другие параметры конструктора на стеке вычислений.
Особый случай применения инструкции newobj связан с созданием экземпляров типов-значений на стеке вычислений. Если указанный во встроенном операнде конструктор принадлежит типу-значению, то новый экземпляр этого типа создается не в куче, а прямо на стеке вычислений.
В таблице 3.26 приведены две инструкции, осуществляющие проверку типа объекта, ссылка на который лежит на вершине стека вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x74 | castclass |
token |
Проверяет, соответствует ли тип объекта на вершине стека. В случае несоответствия генерирует исключение InvalidCastException |
| 0x75 | isinst |
token |
Проверяет, соответствует ли тип объекта на вершине стека. Если соответствует, то оставляет объект на стеке, в противном случае заменяет объект на null |
Диаграмма стека для инструкций проверки типа объекта:
... , obj -> ... , obj
Через инструкции проверки типа объекта реализуются
В таблице 3.27 приведены инструкции, которые загружают на стек вычислений значения и адреса полей объектов, а также сохраняют значения со стека в полях объектов. Токены метаданных во встроенных операндах инструкций указывают на информацию о нужном поле.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x7B | ldfld |
token |
Загружает значение поля объекта. Диаграмма стека:..., obj -> ..., value |
| 0x7C | ldflda |
token |
Загружает адрес поля объекта. Диаграмма стека:..., obj -> ..., addr |
| 0x7D | stfld |
token |
Сохраняет значение в поле объекта. Диаграмма стека:..., obj, value -> ... |
| 0x7E | ldsfld |
token |
Загружает значение ... -> ..., value |
| 0x7F | ldsflda |
token |
Загружает адрес ... -> ..., addr |
| 0x80 | stsfld |
token |
Сохраняет значение в статическом поле объекта. Диаграмма стека:..., val -> ... |
Инструкция callvirt (см. таблицу 3.28) отличается от инструкции call главным образом тем, что адрес вызываемого метода определяется во время выполнения программы путем анализа типа объекта, для которого вызывается метод. Тем самым реализуется идея позднего связывания, необходимая для поддержки полиморфизма.
Диаграмма стека для инструкции callvirt:
... , obj, arg1, ... , argN -> ... , retVal
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x6F | callvirt |
token |
Вызов метода с использованием позднего связывания |
obj ), выполняя поиск принадлежащего этому классу MissingMethodException, но эта ситуация невозможна в верифицированном коде.
Для загрузки на стек вычислений строковых констант предусмотрена отдельная инструкция ldstr, приведенная в таблице 3.29. System.String, копирует в него образ строки и оставляет ссылку на созданный объект на вершине стека вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x72 | ldstr |
token |
Создает на вершине стека объект-строку |
Диаграмма стека для инструкции ldstr:
... -> ... , obj
В принципе, массивы являются такими же объектами, как и экземпляры других классов. Но для более эффективной реализации и для сокращения размеров CIL-кода в наборе инструкций CLI предусмотрена специальная инструкция для работы с одномерными массивами, индексируемыми с нуля.
Инструкция newarr (см. таблицу 3.30) выделяет память под одномерный массив, индексируемый с нуля. Тип элементов массива указывается через
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x8D | newarr |
token |
Создает новый массив с элементами указанного типа |
Диаграмма стека для инструкции newarr:
... , num -> ... , array
Инструкция newarr потребляет со стека вычислений размер массива (на диаграмме обозначен как num ) и оставляет объектную ссылку на созданный массив в куче.
Элементы созданного массива автоматически обнуляются.
Инструкция ldlen (см. таблицу 3.31) загружает размер одномерного массива на стек вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x8E | ldlen |
- | Загружает на стек длину массива |
Диаграмма стека для инструкции ldlen:
... , array -> ... , length
Инструкция потребляет со стека объектную ссылку на массив и оставляет на стеке его размер в виде числа типа native unsigned int.
Инструкции ldelem (см. таблицу 3.32) предназначены для загрузки значения элемента одномерного массива на стек вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x90 | ldelem.i1 |
- | Загрузить элемент типа int8 |
| 0x91 | ldelem.u1 |
- | Загрузить элемент типа unsigned int8 |
| 0x92 | ldelem.i2 |
- | Загрузить элемент типа int16 |
| 0x93 | ldelem.u2 |
- | Загрузить элемент типа unsigned int16 |
| 0x94 | ldelem.i4 |
- | Загрузить элемент типа int32 |
| 0x95 | ldelem.u4 |
- | Загрузить элемент типа unsigned int32 |
| 0x96 | ldelem.i8 (ldelem.u8) |
- | Загрузить элемент типа int64 или unsigned int64 |
| 0x97 | ldelem.i |
- | Загрузить элемент типа native int или unsigned native int |
| 0x98 | ldelem.r4 |
- | Загрузить элемент типа float32 |
| 0x99 | ldelem.r8 |
- | Загрузить элемент типа float64 |
| 0x9A | ldelem.ref |
- | Загрузить элемент - объектную ссылку |
Так как в процессе ldelem.
Следует иметь в виду, что значения целых типов, разрядность которых меньше 32 бит, при загрузке на стек удлиняются. Значения со знаком и значения без знака удлиняются по-разному, поэтому наличие отдельных инструкций для знаковых и беззнаковых целых типов вполне объяснимы. При этом остается неясным, для чего потребовалось определять две инструкции ldelem.i4 и ldelem.u4 для 32-разрядных целых типов, потому что они, очевидно, имеют одинаковый эффект.
Диаграмма стека для инструкций ldelem выглядит следующим образом:
... , array, index -> ... , value
Инструкция потребляет со стека объектную ссылку на массив и индекс элемента (типа native int ), значение которого надо загрузить.
Инструкция ldelema (см. таблицу 3.33) загружает на стек вычислений адрес элемента одномерного массива (управляемый указатель). Тип элементов массива указывается через
... , array, index -> ... , addr
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x8F | ldelema |
token |
Загружает адрес элемента массива с указанным индексом |
Инструкции stelem (см. таблицу 3.34) предназначены для сохранения значения со стека вычислений в элементе одномерного массива. Аналогично инструкциям ldelem, существуют различные варианты stelem для разных типов элементов массива. При этом варианты stelem для беззнаковых целых типов отсутствуют за ненадобностью.
Диаграмма стека для инструкций stelem:
... , array, index, value -> ...
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x9C | stelem.i1 |
- | Сохраняет значение типа int8 в элементе массива с указанным индексом |
| 0x9D | stelem.i2 |
- | Сохраняет значение типа int16 в элементе массива с указанным индексом |
| 0x9E | stelem.i4 |
- | Сохраняет значение типа int32 в элементе массива с указанным индексом |
| 0x9F | stelem.i8 |
- | Сохраняет значение типа int64 в элементе массива с указанным индексом |
| 0xA0 | stelem.r4 |
- | Сохраняет значение типа float32 в элементе массива с указанным индексом |
| 0xA1 | stelem.r8 |
- | Сохраняет значение типа float64 в элементе массива с указанным индексом |
| 0xA2 | stelem.ref |
- | Сохраняет значение объектной ссылки в элементе массива с указанным индексом |
| 0x9B | stelem.i |
- | Сохраняет значение типа native int в элементе массива с указанным индексом |
Специальный набор инструкций предусмотрен для поддержки операций с типами-значениями.
Инструкция initobj (см. таблицу 3.35) предназначена для инициализации значения типа-значения. Во встроенном операнде этой инструкции содержится newobj, инструкция initobj не вызывает конструктор.
Инструкция initobj потребляет со стека вычислений адрес значения:
... , addr -> ...
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xFE 0x15 | initobj |
token |
Заполняет все поля значения нулями |
Инструкция sizeof (см. таблицу 3.36) загружает на стек вычислений размер в байтах типа-значения (размер представляет собой значение типа unsigned int32 ). Во встроенном операнде этой инструкции содержится
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xFE 0x1C | sizeof |
token |
Загружает на стек размер значения указанного типа |
Диаграмма стека для инструкций sizeof:
... -> ... , size
Инструкции, приведенные в таблице 3.37, выполняют копирование значений типов-значений. Во встроенных операндах этих инструкций содержится
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x70 | cpobj |
token |
Копирует значение. Диаграмма стека:..., destAddr, srcAddr ->...(Здесь destAddr - адрес приемника, а srcAddr - адрес источника.) |
| 0x71 | ldobj |
token |
Загружает значение на стек вычислений. Диаграмма стека:..., addr, -> ..., val0bj(Здесь addr - адрес загружаемого значения.) |
| 0x81 | stobj |
token |
Сохраняет значение со стека вычислений в память. Диаграмма стека:..., addr, val0bj ->...(Здесь addr - адрес, по которому будет сохранено значение.) |
Инструкция ldobj используется главным образом при вызове методов для загрузки параметров (если вызываемый метод имеет параметры типов-значений). Инструкции cpobj и stobj применяются сравнительно редко, хотя и имеют однобайтовые коды.
Инструкции, приведенные в таблице 3.38, выполняют упаковку и распаковку значений типов-значений. Во встроенных операндах этих инструкций содержится
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x79 | |
token |
Выполняет распаковку значения. Диаграмма стека..., obj ->..., ptr |
| 0x8C | box |
token |
Упаковывает значение. Диаграмма стека:..., value ->..., obj |
Выполнение инструкции box заключается в создании в куче "объекта-обертки" для значения, после чего осуществляется побитовое копирование значения внутрь "обертки".
При распаковке значения с помощью инструкции никакого копирования не происходит. Вместо этого на стек вычислений загружается адрес значения находящегося внутри "обертки".
Инструкция ldtoken (см. таблицу 3.39) применяется для работы с библиотекой рефлексии. Фактически она переводит токены метаданных в специальные структуры данных рефлексии. Так как переводимый ldtoken представляет собой инструкцию загрузки константы.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xD0 | ldtoken |
token |
Загружает описатель токена метаданных (структуру RuntimeTypeHandle, RuntimeMethodHandle, RuntimeFieldHandle ) |
Диаграмма стека для инструкций ldtoken:
... -> ... , runtimeHandle
Эта инструкция отнесена к группе инструкций для работы с типами-значениями, потому что описатели токенов представляют собой значения типов-значений.
Типизированные ссылки в системе типов .NET реализованы исключительно для поддержки некоторых особенностей синтаксиса и семантики языка Visual Basic .NET. Они представляют собой гибрид управляемого указателя и типа-значения.
Для работы с типизированными ссылками предусмотрены три инструкции CIL, которые мы рассмотрим в этом разделе.
Инструкция mkrefany (см. таблицу 3.40) предназначена для создания типизированных ссылок. Она упаковывает вместе управляемый указатель на некоторое значение и
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xC6 | mkrefany |
token |
Создает типизированную ссылку на вершине стека вычислений |
Диаграмма стека для инструкций mkrefany:
... , ptr -> ... , typedRef
Инструкция refanytype (см. таблицу 3.41) загружает
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xFE 0x1D | refanytype |
- | Загружает |
Диаграмма стека для инструкций refanytype:
... , typedRef -> ... , type
Инструкция refanyval (см. таблицу 3.42) загружает управляемый указатель, хранящийся в типизированной ссылке, на вершину стека вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xC2 | refanyval |
token |
Загружает адрес, хранящийся в типизированной ссылке |
Диаграмма стека для инструкций refanyval:
... , typedRef -> ... , ptr
Язык CIL, в отличие от большинства других ассемблерных языков, содержит богатый набор инструкций, предназначенных для поддержки объектной модели. Этот набор можно разделить на четыре основные категории:
Инструкции для работы с объектами - это базовые инструкции для поддержки объектно-ориентированной парадигмы.
Инструкция newobj (см. таблицу 3.25) выполняет выделение памяти для объекта в куче и затем вызывает для этого объекта конструктор. Операции выделения памяти и вызова конструктора объединены в одной инструкции не случайно, так как это гарантирует отсутствие в куче неинициализированных объектов.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x73 | newobj |
token |
Создает новый объект и вызывает для него конструктор |
Диаграмма стека для инструкции newobj:
... , arg1, ... , argN -> ... , obj
Инструкция newobj потребляет со стека вычислений параметры конструктора и оставляет на стеке ссылку на созданный объект. Параметры вызываемого конструктора должны быть расположены в стеке слева направо, то есть сначала на стек должен быть загружен первый аргумент, затем второй и т.д.
Хотя первым (неявным) параметром для любого конструктора является ссылка на инициализируемый объект (параметр this ), перед вызовом инструкции newobj этот параметр не должен загружаться на стек вычислений. Дело в том, что ссылка на объект формируется в процессе выполнения инструкции (после выделения памяти в куче и до вызова конструктора) и затем автоматически передается конструктору. Происходит как бы "подкладывание" ссылки this под другие параметры конструктора на стеке вычислений.
Особый случай применения инструкции newobj связан с созданием экземпляров типов-значений на стеке вычислений. Если указанный во встроенном операнде конструктор принадлежит типу-значению, то новый экземпляр этого типа создается не в куче, а прямо на стеке вычислений.
В таблице 3.26 приведены две инструкции, осуществляющие проверку типа объекта, ссылка на который лежит на вершине стека вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x74 | castclass |
token |
Проверяет, соответствует ли тип объекта на вершине стека. В случае несоответствия генерирует исключение InvalidCastException |
| 0x75 | isinst |
token |
Проверяет, соответствует ли тип объекта на вершине стека. Если соответствует, то оставляет объект на стеке, в противном случае заменяет объект на null |
Диаграмма стека для инструкций проверки типа объекта:
... , obj -> ... , obj
Через инструкции проверки типа объекта реализуются
В таблице 3.27 приведены инструкции, которые загружают на стек вычислений значения и адреса полей объектов, а также сохраняют значения со стека в полях объектов. Токены метаданных во встроенных операндах инструкций указывают на информацию о нужном поле.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x7B | ldfld |
token |
Загружает значение поля объекта. Диаграмма стека:..., obj -> ..., value |
| 0x7C | ldflda |
token |
Загружает адрес поля объекта. Диаграмма стека:..., obj -> ..., addr |
| 0x7D | stfld |
token |
Сохраняет значение в поле объекта. Диаграмма стека:..., obj, value -> ... |
| 0x7E | ldsfld |
token |
Загружает значение ... -> ..., value |
| 0x7F | ldsflda |
token |
Загружает адрес ... -> ..., addr |
| 0x80 | stsfld |
token |
Сохраняет значение в статическом поле объекта. Диаграмма стека:..., val -> ... |
Инструкция callvirt (см. таблицу 3.28) отличается от инструкции call главным образом тем, что адрес вызываемого метода определяется во время выполнения программы путем анализа типа объекта, для которого вызывается метод. Тем самым реализуется идея позднего связывания, необходимая для поддержки полиморфизма.
Диаграмма стека для инструкции callvirt:
... , obj, arg1, ... , argN -> ... , retVal
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x6F | callvirt |
token |
Вызов метода с использованием позднего связывания |
obj ), выполняя поиск принадлежащего этому классу MissingMethodException, но эта ситуация невозможна в верифицированном коде.
Для загрузки на стек вычислений строковых констант предусмотрена отдельная инструкция ldstr, приведенная в таблице 3.29. System.String, копирует в него образ строки и оставляет ссылку на созданный объект на вершине стека вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x72 | ldstr |
token |
Создает на вершине стека объект-строку |
Диаграмма стека для инструкции ldstr:
... -> ... , obj
В принципе, массивы являются такими же объектами, как и экземпляры других классов. Но для более эффективной реализации и для сокращения размеров CIL-кода в наборе инструкций CLI предусмотрена специальная инструкция для работы с одномерными массивами, индексируемыми с нуля.
Инструкция newarr (см. таблицу 3.30) выделяет память под одномерный массив, индексируемый с нуля. Тип элементов массива указывается через
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x8D | newarr |
token |
Создает новый массив с элементами указанного типа |
Диаграмма стека для инструкции newarr:
... , num -> ... , array
Инструкция newarr потребляет со стека вычислений размер массива (на диаграмме обозначен как num ) и оставляет объектную ссылку на созданный массив в куче.
Элементы созданного массива автоматически обнуляются.
Инструкция ldlen (см. таблицу 3.31) загружает размер одномерного массива на стек вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x8E | ldlen |
- | Загружает на стек длину массива |
Диаграмма стека для инструкции ldlen:
... , array -> ... , length
Инструкция потребляет со стека объектную ссылку на массив и оставляет на стеке его размер в виде числа типа native unsigned int.
Инструкции ldelem (см. таблицу 3.32) предназначены для загрузки значения элемента одномерного массива на стек вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x90 | ldelem.i1 |
- | Загрузить элемент типа int8 |
| 0x91 | ldelem.u1 |
- | Загрузить элемент типа unsigned int8 |
| 0x92 | ldelem.i2 |
- | Загрузить элемент типа int16 |
| 0x93 | ldelem.u2 |
- | Загрузить элемент типа unsigned int16 |
| 0x94 | ldelem.i4 |
- | Загрузить элемент типа int32 |
| 0x95 | ldelem.u4 |
- | Загрузить элемент типа unsigned int32 |
| 0x96 | ldelem.i8 (ldelem.u8) |
- | Загрузить элемент типа int64 или unsigned int64 |
| 0x97 | ldelem.i |
- | Загрузить элемент типа native int или unsigned native int |
| 0x98 | ldelem.r4 |
- | Загрузить элемент типа float32 |
| 0x99 | ldelem.r8 |
- | Загрузить элемент типа float64 |
| 0x9A | ldelem.ref |
- | Загрузить элемент - объектную ссылку |
Так как в процессе ldelem.
Следует иметь в виду, что значения целых типов, разрядность которых меньше 32 бит, при загрузке на стек удлиняются. Значения со знаком и значения без знака удлиняются по-разному, поэтому наличие отдельных инструкций для знаковых и беззнаковых целых типов вполне объяснимы. При этом остается неясным, для чего потребовалось определять две инструкции ldelem.i4 и ldelem.u4 для 32-разрядных целых типов, потому что они, очевидно, имеют одинаковый эффект.
Диаграмма стека для инструкций ldelem выглядит следующим образом:
... , array, index -> ... , value
Инструкция потребляет со стека объектную ссылку на массив и индекс элемента (типа native int ), значение которого надо загрузить.
Инструкция ldelema (см. таблицу 3.33) загружает на стек вычислений адрес элемента одномерного массива (управляемый указатель). Тип элементов массива указывается через
... , array, index -> ... , addr
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x8F | ldelema |
token |
Загружает адрес элемента массива с указанным индексом |
Инструкции stelem (см. таблицу 3.34) предназначены для сохранения значения со стека вычислений в элементе одномерного массива. Аналогично инструкциям ldelem, существуют различные варианты stelem для разных типов элементов массива. При этом варианты stelem для беззнаковых целых типов отсутствуют за ненадобностью.
Диаграмма стека для инструкций stelem:
... , array, index, value -> ...
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x9C | stelem.i1 |
- | Сохраняет значение типа int8 в элементе массива с указанным индексом |
| 0x9D | stelem.i2 |
- | Сохраняет значение типа int16 в элементе массива с указанным индексом |
| 0x9E | stelem.i4 |
- | Сохраняет значение типа int32 в элементе массива с указанным индексом |
| 0x9F | stelem.i8 |
- | Сохраняет значение типа int64 в элементе массива с указанным индексом |
| 0xA0 | stelem.r4 |
- | Сохраняет значение типа float32 в элементе массива с указанным индексом |
| 0xA1 | stelem.r8 |
- | Сохраняет значение типа float64 в элементе массива с указанным индексом |
| 0xA2 | stelem.ref |
- | Сохраняет значение объектной ссылки в элементе массива с указанным индексом |
| 0x9B | stelem.i |
- | Сохраняет значение типа native int в элементе массива с указанным индексом |
Специальный набор инструкций предусмотрен для поддержки операций с типами-значениями.
Инструкция initobj (см. таблицу 3.35) предназначена для инициализации значения типа-значения. Во встроенном операнде этой инструкции содержится newobj, инструкция initobj не вызывает конструктор.
Инструкция initobj потребляет со стека вычислений адрес значения:
... , addr -> ...
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xFE 0x15 | initobj |
token |
Заполняет все поля значения нулями |
Инструкция sizeof (см. таблицу 3.36) загружает на стек вычислений размер в байтах типа-значения (размер представляет собой значение типа unsigned int32 ). Во встроенном операнде этой инструкции содержится
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xFE 0x1C | sizeof |
token |
Загружает на стек размер значения указанного типа |
Диаграмма стека для инструкций sizeof:
... -> ... , size
Инструкции, приведенные в таблице 3.37, выполняют копирование значений типов-значений. Во встроенных операндах этих инструкций содержится
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x70 | cpobj |
token |
Копирует значение. Диаграмма стека:..., destAddr, srcAddr ->...(Здесь destAddr - адрес приемника, а srcAddr - адрес источника.) |
| 0x71 | ldobj |
token |
Загружает значение на стек вычислений. Диаграмма стека:..., addr, -> ..., val0bj(Здесь addr - адрес загружаемого значения.) |
| 0x81 | stobj |
token |
Сохраняет значение со стека вычислений в память. Диаграмма стека:..., addr, val0bj ->...(Здесь addr - адрес, по которому будет сохранено значение.) |
Инструкция ldobj используется главным образом при вызове методов для загрузки параметров (если вызываемый метод имеет параметры типов-значений). Инструкции cpobj и stobj применяются сравнительно редко, хотя и имеют однобайтовые коды.
Инструкции, приведенные в таблице 3.38, выполняют упаковку и распаковку значений типов-значений. Во встроенных операндах этих инструкций содержится
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0x79 | |
token |
Выполняет распаковку значения. Диаграмма стека..., obj ->..., ptr |
| 0x8C | box |
token |
Упаковывает значение. Диаграмма стека:..., value ->..., obj |
Выполнение инструкции box заключается в создании в куче "объекта-обертки" для значения, после чего осуществляется побитовое копирование значения внутрь "обертки".
При распаковке значения с помощью инструкции никакого копирования не происходит. Вместо этого на стек вычислений загружается адрес значения находящегося внутри "обертки".
Инструкция ldtoken (см. таблицу 3.39) применяется для работы с библиотекой рефлексии. Фактически она переводит токены метаданных в специальные структуры данных рефлексии. Так как переводимый ldtoken представляет собой инструкцию загрузки константы.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xD0 | ldtoken |
token |
Загружает описатель токена метаданных (структуру RuntimeTypeHandle, RuntimeMethodHandle, RuntimeFieldHandle ) |
Диаграмма стека для инструкций ldtoken:
... -> ... , runtimeHandle
Эта инструкция отнесена к группе инструкций для работы с типами-значениями, потому что описатели токенов представляют собой значения типов-значений.
Типизированные ссылки в системе типов .NET реализованы исключительно для поддержки некоторых особенностей синтаксиса и семантики языка Visual Basic .NET. Они представляют собой гибрид управляемого указателя и типа-значения.
Для работы с типизированными ссылками предусмотрены три инструкции CIL, которые мы рассмотрим в этом разделе.
Инструкция mkrefany (см. таблицу 3.40) предназначена для создания типизированных ссылок. Она упаковывает вместе управляемый указатель на некоторое значение и
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xC6 | mkrefany |
token |
Создает типизированную ссылку на вершине стека вычислений |
Диаграмма стека для инструкций mkrefany:
... , ptr -> ... , typedRef
Инструкция refanytype (см. таблицу 3.41) загружает
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xFE 0x1D | refanytype |
- | Загружает |
Диаграмма стека для инструкций refanytype:
... , typedRef -> ... , type
Инструкция refanyval (см. таблицу 3.42) загружает управляемый указатель, хранящийся в типизированной ссылке, на вершину стека вычислений.
| Код | Инструкция | Встроенный операнд | Описание |
|---|---|---|---|
| 0xC2 | refanyval |
token |
Загружает адрес, хранящийся в типизированной ссылке |
Диаграмма стека для инструкций refanyval:
... , typedRef -> ... , ptr
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.