Как использовать относительное положение в с / сборке? - PullRequest
5 голосов
/ 03 апреля 2011

Говорят, Независимый от позиции код использует только относительную позицию вместо абсолютных позиций, как это реализовано в c и ассемблере соответственно?

Давайте возьмем char test[] = "string"; в качестве примера, как ссылаться на него по относительному адресу?

Ответы [ 3 ]

2 голосов
/ 03 апреля 2011

На x86 позиционно-независимый код в принципе выглядит так:

        call 1f
1:      popl %ebx

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

В действительности это часто более сложно, и обычно для загрузки регистра PIC может использоваться функция крошечного thunk:

load_ebx:
        movl 4(%esp),%ebx
        addl $some_offset,%ebx
        ret

, где смещение выбрано таким образом, чтобы при возврате thunk ebx содержал указатель на обозначенную специальную точку в программе / библиотеке (обычно начало глобальной таблицы смещений), а затем все последующие ebx -относительные доступы могут просто использовать расстояние между требуемыми данными и назначенной специальной точкой в ​​качестве смещения.

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

2 голосов
/ 03 апреля 2011

В C позиционно-независимый код - это деталь реализации компилятора. См. Руководство к вашему компилятору, чтобы определить, поддерживается ли он и как.

В сборке позиционно-независимый код является деталью архитектуры набора команд. Обратитесь к руководству по вашему ЦП, чтобы узнать, как читать регистр ПК (счетчик программ), насколько он эффективен и каковы рекомендуемые рекомендации по преобразованию кодового адреса в адрес данных.

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

0 голосов
/ 03 апреля 2011

В псевдокоде это может выглядеть так:

lea str1(pc), r0 ; load address of string relative to the pc (assuming constant strings, maybe)
st r0, test  ; save the address in test (test could also be PIC, in which case it could be relative
             ; to some register)

Многое зависит от вашего компилятора и архитектуры процессора, как указано в предыдущем ответе. Один из способов выяснить это - скомпилировать с соответствующими флагами (-PIC -S для gcc) и посмотреть на нужный язык ассемблера.

...