#.net #cil #opcode
#.net #cil #код операции
Вопрос:
Я пытаюсь разобраться с некоторым кодом CIL. Но, похоже, эти два оператора выполняют одно и то же (согласно всему, что я прочитал).
ldc.i4 33
и
ldc.i4.33
Оба предположительно «загружают int32 в стек значений 33».
Это правильно? Почему? Я бы подумал, что ldc.i4.33
это будет «загрузить целое число из локальной переменной index 33 в стек».
Где я здесь ошибаюсь?
Комментарии:
1. ldc.i4.33 не существует. Могу я спросить, откуда вы это взяли? Список допустимых кодов операций можно найти в ECMA-335, раздел III, раздел 1.2.1
2. Ну, я видел ldc.i4.1, и я видел ldc.i4 33, и я не знал, что существуют «коды операций с макросами», поэтому я предположил, что ldc.i4.33 — это то же самое, но меня это смутило.
Ответ №1:
Код операции ldc.i4.33
не существует.
Есть несколько специальных (называемых макросами) кодов операций, из:
ldc.i4.m1 // has the same effect as: ldc.i4 -1
Для
ldc.i4.8 // has the same effect as: ldc.i4 8
Но они представляют собой всего лишь краткую форму ldc.i4
кода операции, для обычных случаев, для оптимизации размера CIL.
Аналогично, ldloc.0
является короткой формой (т. Е. имеет более компактную CIL-кодировку, но выполняет точно то же самое, что и) ldloc 0
и т.д.
Комментарии:
1. Ох. Неудивительно, что я был сбит с толку. Так что это тоже допустимый код операции, я так понимаю (что и вызвало мое замешательство): ldc.i4.0 ? И я думаю, что ldloc — это код операции для хранения значения локальной переменной в стеке, например, ldloc.2 хранит значение локальной переменной index 2 в стеке. Все ли это правильно?
2. Нет, ld — это префикс для load. Итак,
ldloc.2
загружает переменную с индексом 2 в стек. st — это префикс для хранилища, поэтомуstloc.2
сохраняет значение в стеке в переменной с индексом 2. И да,ldc.i4.0
является допустимым кодом операции и представляет собой краткую формуldc.i4 0
3. JB: Именно это я и имел в виду, я просто использовал слово «хранить» как синоним «загружать», что неверно ( хлопает по запястью ). Спасибо за разъясняющие ответы!