2015-07-26 8 views
1

Я создал прототип виртуальной машины на Java (так как это язык, на котором я наиболее удобен), и я пытаюсь сохранить инструкции в формате байт-кода. Мне интересно, как я могу хранить ценности в байткод, так как байт s может быть только 0 до 255.Сохранение значений в формате байткода

В качестве примера:

push 4752 

Нажмите будет иметь значение опкода 0. Но как я могу сохранить 4752? Он не вписывается в один байт. Я мог хранить значения в 4 байтах, что позволяло им быть 32-битными целыми числами, но тогда мне пришлось бы решить, нужно ли загружать код операции (1 байт) или значение (4 байта). В настоящее время я передаю программу как целочисленный массив, а виртуальная петля проходит через массив и выполняет коды операций. Если код операции требует значения, он берет его из массива, а затем увеличивает счетчик программ, чтобы пропустить значение, чтобы он не выполнялся.

Я попытался выяснить, как виртуальные машины, такие как JVM, делают это, но я не смог это выяснить.

ответ

3

JVM имеет несколько вариантов, позволяющих более короткое кодирование случаев, которые, как ожидается, будут более частыми, и, следовательно, в среднем меньшее кодирование методов и классов. Конкретно см следующие инструкции под https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5 (или SE8, но IIRC ни один из базовых инструкций арифметика/вычисления не были изменены между 7 и 8, только один или два из вызова инструкции):

  • iconst_ < я > являются индивидуальными опкодами, которые толкают определенные значения «m1» (-1) через 5
  • bipush толкают следующие один-байты из потока команд
  • sipush толкает следующие два байта из потока команд
  • LDC или ldc_w толкает значение четырех байт из постоянного пула, выбранное с помощью индекса в потоке команд

Ваш пример значения 4752 подходит в двух байтах и ​​будет использовать sipush.

Чтобы продлить вопрос, long (64-битные или 8-байтовые) Значения в JVM, в основном, созданные толкания int затем расширение его, или пути нажатия значения из long переменного или полей (или возврата метода). Существует одна инструкция ldc2_w нажать значение в 2-элементный (8-байтовый) от постоянного пула, и два специальных-за частые инструкции lconst_0 и lconst_1 для 0 и 1.

+0

спасибо, это похоже на решение :) –