Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 52 стр.

UptoLike

3.2.1.3. Косвенная загрузка и сохранение значений
При косвенной загрузке и сохранении значений работа с памятью
осуществляется через адреса (управляемые и неуправляемые указатели).
Особенностью инструкций данной группы является наличие разных
инструкций для работы со значениями разных типов. Причина в том, что
при загрузке или сохранении значения бывает необходимо выполнить его
преобразование к другому типу, а так как JIT-компилятор в процессе ком-
пиляции не собирает информацию о типах управляемых указателей, ему
надо явно указывать тип загружаемых и сохраняемых значений. Необхо-
димость выполнения преобразований объясняется тем, что не все прими-
тивные типы могут находиться на стеке вычислений (поэтому, например,
значение типа int8 при загрузке на стек расширяется до int32).
В таблице 3.6 перечислены инструкции для косвенной загрузки зна-
чений. Обратите внимание, что инструкции ldind.i8 и ldind.u8 являются
псевдонимами (имеют один и тот же код). Дело в том, что загрузка любых
64-разрядных целых значений на стек не вызывает их преобразования,
ибо хотя на стеке не предусмотрено наличие беззнаковых 64-разрядных
значений, их загрузка все равно сводится к простому побитовому копиро-
ванию. Вышесказанное справедливо также и для 32-разрядных целых
значений, но для их загрузки зачем-то зарезервировано сразу две инст-
рукции.
Диаграмма стека для инструкций косвенной загрузки выглядит сле-
дующим образом:
... , address -> ... , value
Инструкций для косвенного сохранения значений (см. таблицу 3.7)
меньше, чем инструкций для косвенной загрузки (можно заметить, что
инструкции для сохранения значений беззнаковых целых типов отсутст-
вуют). Причина в том, что сохранение беззнаковых целых ничем не отли-
чается от сохранения знаковых целых.
Диаграмма стека для инструкций косвенного сохранения выглядит
следующим образом:
... , address , value -> ...
3.2.1.4. Специальные инструкции для работы со стеком
В отличие от «железных» стековых процессоров, CLI не содержит
развитой системы инструкций для чисто стековых манипуляций. В табли-
це 3.8 представлены две имеющиеся в наличии инструкции.
3.2.2. Арифметические инструкции
Арифметические инструкции можно разделить на четыре категории:
бинарные операции;
унарные операции;
Common Intermediate Language
91
Инструкции, представленные в таблице 3.5, выполняют сохранение
значения на вершине стека в переменную или параметр. Они имеют сле-
дующую диаграмму стека:
... , value -> ...
90
CIL и системное программирование в Microsoft .NET
Код Инструкция Встроенный Описание
операнд
0x0F ldarga.s unsigned Загрузка адресов параметров с
int8 номерами от 0 до 255
0x12 ldloca.s unsigned Загрузка адресов локальных
int8 переменных с номерами
от 0 до 255
0xFE 0x0A ldarga unsigned Загрузка адресов параметров
int16 с номерами от 0 до 65534
0xFE 0x0D ldloca unsigned Загрузка адресов локальных
int16 переменных с номерами
от 0 до 65534
Таблица 3.4. Инструкции для загрузки адресов параметров и локаль-
ных переменных
Код Инструкция Встроенный Описание
операнд
0x0A – 0x0D stloc.0 – – Сохранение значений
stloc.3 в локальных переменных
с номерами от 0 до 3
0x10 starg.s unsigned Сохранение значений
int8 в параметрах с номерами
от 0 до 255
0x13 stloc.s unsigned Сохранение значений
int8 в локальных переменных
с номерами от 0 до 255
0xFE 0x0B starg unsigned Сохранение значений
int16 в параметрах с номерами
от 0 до 65534
0xFE 0x0E stloc unsigned Сохранение значений
int16 в локальных переменных
с номерами от 0 до 65534
Таблица 3.5. Инструкции для сохранения значений в параметрах и
локальных переменных
90                          CIL и системное программирование в Microsoft .NET   Common Intermediate Language                                         91


      Таблица 3.4. Инструкции для загрузки адресов параметров и локаль-         3.2.1.3. Косвенная загрузка и сохранение значений
      ных переменных                                                                 При косвенной загрузке и сохранении значений работа с памятью
                                                                                осуществляется через адреса (управляемые и неуправляемые указатели).
Код           Инструкция Встроенный     Описание
                                                                                     Особенностью инструкций данной группы является наличие разных
                         операнд                                                инструкций для работы со значениями разных типов. Причина в том, что
0x0F          ldarga.s   unsigned       Загрузка адресов параметров с           при загрузке или сохранении значения бывает необходимо выполнить его
                         int8           номерами от 0 до 255                    преобразование к другому типу, а так как JIT-компилятор в процессе ком-
0x12          ldloca.s   unsigned       Загрузка адресов локальных              пиляции не собирает информацию о типах управляемых указателей, ему
                         int8           переменных с номерами                   надо явно указывать тип загружаемых и сохраняемых значений. Необхо-
                                        от 0 до 255                             димость выполнения преобразований объясняется тем, что не все прими-
0xFE 0x0A     ldarga      unsigned      Загрузка адресов параметров             тивные типы могут находиться на стеке вычислений (поэтому, например,
                          int16         с номерами от 0 до 65534                значение типа int8 при загрузке на стек расширяется до int32).
0xFE 0x0D     ldloca      unsigned      Загрузка адресов локальных                   В таблице 3.6 перечислены инструкции для косвенной загрузки зна-
                          int16         переменных с номерами                   чений. Обратите внимание, что инструкции ldind.i8 и ldind.u8 являются
                                                                                псевдонимами (имеют один и тот же код). Дело в том, что загрузка любых
                                        от 0 до 65534
                                                                                64-разрядных целых значений на стек не вызывает их преобразования,
     Инструкции, представленные в таблице 3.5, выполняют сохранение             ибо хотя на стеке не предусмотрено наличие беззнаковых 64-разрядных
значения на вершине стека в переменную или параметр. Они имеют сле-             значений, их загрузка все равно сводится к простому побитовому копиро-
дующую диаграмму стека:                                                         ванию. Вышесказанное справедливо также и для 32-разрядных целых
     ... , value -> ...                                                         значений, но для их загрузки зачем-то зарезервировано сразу две инст-
                                                                                рукции.
      Таблица 3.5. Инструкции для сохранения значений в параметрах и                 Диаграмма стека для инструкций косвенной загрузки выглядит сле-
      локальных переменных                                                      дующим образом:
                                                                                     ... , address -> ... , value
Код         Инструкция Встроенный Описание                                           Инструкций для косвенного сохранения значений (см. таблицу 3.7)
                       операнд                                                  меньше, чем инструкций для косвенной загрузки (можно заметить, что
0x0A – 0x0D stloc.0 –  –          Сохранение значений                           инструкции для сохранения значений беззнаковых целых типов отсутст-
            stloc.3               в локальных переменных                        вуют). Причина в том, что сохранение беззнаковых целых ничем не отли-
                                  с номерами от 0 до 3                          чается от сохранения знаковых целых.
0x10        starg.s    unsigned   Сохранение значений                                Диаграмма стека для инструкций косвенного сохранения выглядит
                       int8       в параметрах с номерами                       следующим образом:
                                  от 0 до 255                                        ... , address , value -> ...
0x13        stloc.s    unsigned   Сохранение значений
                                                                                3.2.1.4. Специальные инструкции для работы со стеком
                       int8       в локальных переменных
                                                                                     В отличие от «железных» стековых процессоров, CLI не содержит
                                  с номерами от 0 до 255
                                                                                развитой системы инструкций для чисто стековых манипуляций. В табли-
0xFE 0x0B starg        unsigned   Сохранение значений                           це 3.8 представлены две имеющиеся в наличии инструкции.
                       int16      в параметрах с номерами
                                  от 0 до 65534                                 3.2.2. Арифметические инструкции
0xFE 0x0E stloc        unsigned   Сохранение значений                                Арифметические инструкции можно разделить на четыре категории:
                       int16      в локальных переменных                               • бинарные операции;
                                  с номерами от 0 до 65534                             • унарные операции;