Что делает регистр PIC (% ebx)? - PullRequest
10 голосов
/ 04 июня 2009

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

Я делаю это вручную, изменяя базовый адрес стека (настройка %ebp) и переходя на адрес метки. Он полностью работает, как с gcc, так и с icc, без какого-либо повреждения стека. День, когда это сработало, был классным.

Сейчас я беру ту же программу и переписываю ее на C, и она не работает. В частности, он не работает с gcc v4.0.1 (Mac OS). Как только я перехожу к новому фрейму стека (с правильно установленным указателем стека), выполняются следующие инструкции перед вызовом fprintf. Последняя инструкция, указанная здесь, вылетает, разыменовывая NULL:

lea    0x18b8(%ebx), %eax
mov    (%eax), %eax
mov    (%eax), %eax

Я провел некоторую отладку и выяснил, что, установив регистр %ebx вручную, когда я переключаю кадры стека (используя значение, которое я наблюдал, прежде чем покинуть функцию в первую очередь), я исправляю ошибку , Я читал, что этот регистр имеет дело с "позиционно-независимым кодом" в gcc.

Что такое независимый от позиции код? Как работает независимый от позиции код? На что указывает этот регистр?

Ответы [ 2 ]

15 голосов
/ 04 июня 2009

EBX указывает на глобальную таблицу смещений. См. эту ссылку о PIC на i386 . Ссылка объясняет, как используется PIC EBX.

7 голосов
/ 04 июня 2009

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

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

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

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

...