Выровнять собственный код на границах памяти фиксированного размера с GCC / G ++ / AS? - PullRequest
4 голосов
/ 30 июля 2009

У меня есть функция C, которая содержит весь код, который будет реализовывать байт-коды интерпретатора байт-кода.

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

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

Если это вообще возможно, как я скажу компилятору / ассемблеру (gcc / g ++ / as) выполнить выравнивание указанным способом?

Ответы [ 3 ]

7 голосов
/ 30 июля 2009

Я понимаю, что это не совсем то, что вы просите, но это стандартный способ реализации интерпретаторов байтового кода с GCC.

Функция GCC «вычисление перехода» или «метки как значения» позволяет размещать метки в массиве и эффективно переходить к различным инструкциям байт-кода. См. Быстрый интерпретатор, использующий вычисленную GCC команду Goto . Также посмотрите на этот связанный вопрос переполнения стека: C / C ++ goto и документацию GCC для меток как значений .

Код для этого будет выглядеть примерно так:

void* jumptable[] = {&&label1, &&label2};

label:
  /* Code here... */

label2:
  /* Other code here... */

Затем вы можете перейти к другим инструкциям, используя таблицу:

goto *jumptable[i];
0 голосов
/ 27 августа 2009

Если вы используете Linux, используйте posix_memalign (). Я уверен, что есть аналогичная функция для Windows.

Если вы хотите выровнять свой собственный код, взгляните на синтаксис gcc __attribute__.

Параметры ld -Ttext также могут быть полезны.

0 голосов
/ 31 июля 2009

Здесь есть два вопроса, но ответ тот же. Сначала вы записываете (двоичные) данные в (двоичный) файл. Во-вторых, вы загружаете эти (двоичные) данные в память. Вы контролируете, куда он попадает на диск, и вы контролируете, куда он идет в памяти. Вы можете легко рассчитать, что вы ищете.

Лично я, вероятно, использовал бы массив при загрузке данных в память, и я бы удостоверился, что все данные начинаются с допустимого индекса в этом массиве. Массивы расположены непрерывно и с ними относительно легко работать. В книге Кернигана и Ричи Язык программирования C упоминается методика использования union s для выравнивания, но это не упрощает арифметику указателей.

...