Московский государственный технический университет им. Н.Э. Баумана
Опубликован: 28.06.2006 | Доступ: свободный | Студентов: 12463 / 341 | Оценка: 4.54 / 3.83 | Длительность: 22:03:00
ISBN: 978-5-9556-0055-0
Лекция 5:

Common Intermediate Language

< Лекция 4 || Лекция 5: 123 || Лекция 6 >

Инструкции для организации передачи управления

Инструкции для организации передачи управления можно разделить на пять категорий:

  • инструкции безусловного перехода;
  • инструкции условного перехода;
  • инструкция множественного выбора switch;
  • инструкция вызова метода call;
  • инструкция возврата из метода ret.
Безусловный переход

Существуют две инструкции безусловного перехода (см. таблицу 3.18), которые различаются только разрядностью встроенного операнда ( int8 и int32 ). При этом встроенный операнд этих инструкций обозначает относительное смещение цели перехода.

Таблица 3.18. Инструкции безусловного перехода
Код Инструкция Встроенный операнд Описание
0x2B br.s int8 Короткий безусловный переход
0x38 br. int32 Длинный безусловный переход
Условный переход

Базовые инструкции условного перехода, приведенные в таблице 3.19, потребляют со стека вычислений один операнд и, в зависимости от его значения, осуществляют или не осуществляют переход по указанному во встроенном операнде относительному адресу. Диаграмма стека для этих инструкций выглядит следующим образом:

... , value -> ...
Таблица 3.19. Базовые инструкции условного перехода
Код Инструкция Встроенный операнд Описание
0x2C brfalse.s int8 Короткий условный переход, если значение равно 0 или null
0x2D brtrue.s int8 Короткий условный переход, если значение не равно 0 или null
0x39 brfalse int32 Длинный условный переход, если значение равно 0 или null
0x3A brtrue int32 Длинный условный переход, если значение не равно 0 или null

Как и в случае инструкций безусловного перехода, существуют короткий и длинный варианты инструкций условного перехода, которые отличаются только разрядностью встроенного операнда ( int8 и int32 ).

Инструкции brfalse присвоены два псевдонима: brnull и brzero, имеющих одинаковый с ней код. Аналогично, brfalse.s имеет псевдонимы brnull.s и brzero.s.

Кроме базовых, существуют дополнительные инструкции условного перехода, потребляющие сразу два операнда. Каждая из дополнительных инструкций условного перехода является сокращенной записью последовательности из двух инструкций, первая из которых является бинарной операцией сравнения, а вторая - базовой инструкцией условного перехода.

Таким образом, дополнительные инструкции условного перехода имеют следующую диаграмму стека:

... , value1 , value2 -> ...

Длинные варианты дополнительных инструкций условного перехода перечислены в таблице 3.20, а короткие - в таблице 3.21. В описании каждой инструкции приводится эквивалентная ей комбинация бинарной операции сравнения и базовой инструкции условного перехода. В связи с тем, что семантика операций сравнения для целых чисел существенно отличается от их семантики для чисел с плавающей запятой, для инструкций bge, ble, bge.un и ble.un (и для коротких вариантов этих инструкций) приводится по две эквивалентные им комбинации. Комбинация, помеченная меткой ( int ), используется в случае целых операндов, а комбинация, помеченная меткой ( F ), используется в том случае, если операнды представляют собой числа с плавающей запятой.

Таблица 3.20. Дополнительные длинные инструкции условного перехода
Код Инструкция Встроенный операнд Описание
0x3B beq int32 ceq; brtrue
0x3C bge int32
(int): clt; brfalse
(F) : clt.un; brfalse
0x3D bgt int32 cgt; brtrue
0x3E ble int32
(int): cgt; brfalse
(F) : cgt.un; brfalse
0x3F blt int32 clt; brtrue
0x40 bne.un int32 ceq; brfalse
0x41 bge.un int32
(int): clt.un; brfalse
(F) : clt; brfalse
0x42 bgt.un int32 cgt.un; brtrue
0x43 ble.un int32
(int): cgt.un; brfalse
(F) : cgt; brfalse
0x44 blt.un int32 clt.un; brtrue

Таблица 3.21. Дополнительные короткие инструкции условного перехода
Код Инструкция Встроенный операнд Описание
0x2E beq.s int8 ceq; brtrue.s
0x2F bge.s int8
(int): clt; brfalse.s
(F) : clt.un; brfalse.s
0x30 bgt.s int8 cgt; brtrue.s
0x31 ble.s int8
(int): cgt; brfalse.s
(F) : cgt.un; brfalse.s
0x32 blt.s int8 clt; brtrue.s
0x33 bne.un.s int8 ceq; brfalse.s
0x34 bge.un.s int8
(int): clt.un; brfalse.s
(F) : clt; brfalse.s
0x35 bgt.un.s int8 cgt.un; brtrue.s
0x36 ble.un.s int8
(int): cgt.un; brfalse.s
(F) : cgt; brfalse.s
0x37 blt.un.s int8 clt.un; brtrue.s
Инструкция switch

Инструкция множественного выбора switch представлена в таблице 3.22. Встроенный операнд этой инструкции имеет сложный формат: первое 32-разрядное слово содержит размер N таблицы переходов, после чего следует N 32-рязрядных относительных смещений целей перехода.

Инструкция switch берет со стека вычислений один операнд. Обозначим этот операнд через I. Значение I интерпретируется как целое число без знака и сравнивается с N. Если I < N, то управление передается на I-тую цель в таблице переходов (нумерация целей осуществляется с 0). Если I >= N, то управление передается на инструкцию, непосредственно следующую за инструкцией switch.

Для инструкции switch можно записать следующую диаграмму стека:

... , value -> ...
Таблица 3.22. Инструкция switch
Код Инструкция Встроенный операнд Описание
0x45 switch
unsigned
int32,
int32,...
int32,
Осуществляет переход по таблице переходов в соответствии со значением на вершине стека
Инструкция call

Инструкция call (см. таблицу 3.23) выполняет вызов метода, который указан во встроенном операнде инструкции. Встроенный операнд представляет собой токен метаданных, указывающий на описывающую вызываемый метод запись в таблицах метаданных. Непосредственно перед инструкцией call может стоять префикс .tail, который говорит о том, что состояние текущего метода должно быть освобождено перед передачей управления вызываемому методу (хвостовой вызов).

Таблица 3.23. Инструкция call
Код Инструкция Встроенный операнд Описание
0x28 call token Выполняет вызов метода

Информация о методе, на которую указывает токен метаданных, позволяет JIT-компилятору определить, является ли вызываемый метод статическим, экземплярным, виртуальным или глобальной функцией. Особенностью инструкции call (по сравнению с инструкцией callvirt, которую мы будем рассматривать далее в этой главе) является то, что адрес вызываемого метода вычисляется статически, то есть еще во время JIT-компиляции.

Параметры вызываемого метода должны быть расположены в стеке слева направо, то есть сначала на стек должен быть загружен первый параметр, затем второй и т.д. При вызове экземплярного метода в качестве первого параметра должна выступать объектная ссылка (параметр this ).

Если вызываемый метод возвращает значение, то оно загружается на стек вызывающего метода.

Инструкция ret

Инструкция ret (см. таблицу 3.24) осуществляет возврат из метода. Если метод возвращает значение, то оно должно быть загружено на вершину стека вычислений.

Таблица 3.24. Инструкция ret
Код Инструкция Встроенный операнд Описание
0x2A ret - Осуществляет возврат из метода
< Лекция 4 || Лекция 5: 123 || Лекция 6 >
Анастасия Булинкова
Анастасия Булинкова
Рабочим названием платформы .NET было