Как разгрузить вычисление смещения памяти из времени выполнения в C/C++?

Я реализую простую виртуальную машину, и в настоящее время я использую арифметику времени выполнения для вычисления адресов отдельных программных объектов как смещений от базовых указателей.

Я задал сегодня пару вопросов по теме, но, кажется, я потихоньку иду в никуда.

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

И из вопроса два-Разрешены ли смещения адресов во время компиляции в C/C++?-Я узнал, что нет никакой гарантии, что это произойдет при выполнении смещений вручную.

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

Я использую GCC, что касается платформы -. Я разрабатываю для x86 в Windows, но, поскольку это виртуальная машина, я хотел бы, чтобы она эффективно работала на всех платформах, поддерживаемых GCC.

Поэтому ЛЮБАЯ информация по этому вопросу приветствуется и будет очень признательна.

Заранее спасибо!

РЕДАКТИРОВАТЬ :Некоторый обзор моей генерации программного кода -на этапе проектирования программа строится как древовидная иерархия, которая затем рекурсивно сериализуется в один непрерывный блок памяти,наряду с индексацией объектов и вычислением их смещения от начала блока памяти программы.

РЕДАКТИРОВАТЬ 2 :Вот некоторый псевдокод виртуальной машины:

switch *instruction
   case 1: call_fn1(*(instruction+1)); instruction += (1+sizeof(parameter1)); break;
   case 2: call_fn2(*(instruction+1), *(instruction+1+sizeof(parameter1));
           instruction += (1+sizeof(parameter1)+sizeof(parameter2); break;
   case 3: instruction += *(instruction+1); break;  

Случай 1 — это функция, которая принимает один параметр, который находится сразу после инструкции, поэтому он передается как смещение в 1 байт от инструкции. Указатель инструкции увеличивается на 1 + размер первого параметра, чтобы найти следующую инструкцию.

Случай 2 — это функция, которая принимает два параметра, как и раньше: первый параметр передается как смещение в 1 байт, второй параметр передается как смещение в 1 байт плюс размер первого параметра. Затем указатель инструкции увеличивается на размер инструкции плюс размеры обоих параметров.

Случай 3 — оператор goto, указатель инструкции увеличивается на смещение, которое следует непосредственно за инструкцией goto.

РЕДАКТИРОВАТЬ 3 :Насколько я понимаю, ОС будет предоставлять каждому процессу свое собственное адресное пространство виртуальной памяти. Если да, значит ли это, что первый адрес всегда... ну нулевой, так что смещение от первого байта блока памяти на самом деле является самим адресом этого элемента? Если адрес памяти предназначен для каждого процесса, и я знаю смещение блока памяти моей программы И смещение каждого объекта программы от первого байта блока памяти, то разрешаются ли адреса объектов во время компиляции?

Проблема в том, что эти смещения недоступны во время компиляции кода C, они становятся известны на этапе «компиляции» и трансляции в байт-код. Означает ли это, что невозможно вычислить адрес памяти объекта «бесплатно»?

Как это делается, например, в Java, где только виртуальная машина компилируется в машинный код, означает ли это, что вычисление адресов объектов снижает производительность из-за арифметики времени выполнения?

6
задан Community 23 May 2017 в 12:12
поделиться