Выровнять собственный код по границам памяти фиксированного размера с GCC / G ++ / AS?

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

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

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

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


person mcjabberz    schedule 30.07.2009    source источник


Ответы (3)


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

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

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

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

label:
  /* Code here... */

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

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

goto *jumptable[i];
person Ville Laurikari    schedule 30.07.2009

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

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

person Max Lybbert    schedule 30.07.2009

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

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

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

person teambob    schedule 27.08.2009