Я понимаю, что iload принимает целые числа от -1 до 5, но как вы можете расширить их до более высоких чисел с помощью инструкции bipush? Как конкретное целое число сохраняется с байт-кодом?
Как работает bipush в JVM?
Ответы (2)
Есть несколько разных инструкций, которые можно использовать для вставки целочисленной константы.
Самая маленькая - это инструкция iconst_ *. Это всего лишь один байт, потому что значение закодировано в самом коде операции. iconst_1, iconst_2 и т. д. - разные коды операций. iconst_5
, например, будет закодирован как байт 08
.
Примечание: iload
- это совершенно не связанная инструкция, используемая для загрузки значения локальной переменной. Вы, должно быть, думали о iconst_ *.
Далее идет bipush
, который может помещать константу между -128 и 127. Длина этой инструкции составляет два байта: первый байт - это код операции, а второй байт - это 8-битное целое число со знаком. Вы даже можете использовать его для передачи констант в диапазоне от -1 до 5, хотя это займет больше места в файле классов, чем необходимо. Например, bipush 5
будет закодирован как 10 05
. (0x10 - код операции для bipush)
Далее идет sipush
, который является таким же, за исключением того, что он хранит 16-битную константу вместо 8-битной константы, и, следовательно, длина инструкции составляет три байта. Код операции для sipush - 0x11, поэтому sipush 5
будет закодирован как трехбайтовая последовательность 11 00 05
.
Вы можете задаться вопросом, как хранятся целочисленные константы, не умещающиеся в 16 битах. В этом случае компилятор создает записи в отдельном разделе файла классов, называемом пулом констант, а затем использует инструкцию ldc
или ldc_w
для ссылки на запись пула констант.
Я думаю, вы ищете раздел 2.11 JVMS, который касается представления инструкций. В частности, он использует очевидный порядок: код операции, сразу за которым следуют операнды по порядку, с прямым порядком байтов (как и все представления Java). В случае bipush
это будет байт 0x10, за которым следует буквальное значение.
iload
), или о добавлении литералов с помощьюbipush
. - person chrylis -cautiouslyoptimistic-   schedule 04.05.2018iload_1
помещаетint
из локальной переменной №1 (второй, так как она начинается с нуля) в стек. - person chrylis -cautiouslyoptimistic-   schedule 04.05.2018