За всеми этими разговорами мы чуть было не забыли о третьем способе формирования адреса в программе. Это относительная адресация, когда адрес получается сложением адресного поян команды и адреса самой этой команды — значения счетчика команд. Код, в котором используется только такая адресация, можно загружать с любого адреса без всякой перенастройки. Такой код называется позиционно-независимый {position-independent).
Позиционно-независимые программы очень удобны для загрузки, но, к сожалению, при их написании следует соблюдать довольно жесткие ограничения, накладываемые на используемые в программе методы адресации. Например, нельзя пользоваться статически и ни и и ал изо ванны ми переменными указательного типа, нельзя делать на ассемблере фокусы и т. д. Возникают сложности при сборке программы из нескольких модулей.
К тому же, на многих процессорах, например, на Intel 80S0/8085 или многих современных RISC-процессорах, описанная выше реализация позиционно-независимого кода вообще невозможна, так как эти процессоры не поддерживают соответствующий режим адресации для данных. На процессорах гарвардской архитектуры адресовать данные относительно счетчика команд вообще невозможно — команды находятся в другом адресном пространстве.
Поэтому такой стиль программирования используют только в особых случаях. Например, многие вирусы для MS DOS и драйверы для RT-11 написаны именно таким образом.
Компиляторы современных систем семейства UNIX — GNU С или стандартный С-компилятор UNIX SVR4 имеют ключ -f PIC (Position-Independent Code}. Впрочем, код, порождаемый при использовании этого ключа, не является позиционно-независимым в указанном выше смысле: этот код все-таки содержит перемещаемые адресные ссылки. Задача состоит не в том, чтобы избавиться от таких ссылок полностью, а лишь в том, чтобы собрать все эти ссылки в одном месте и разместить их, по возможности, отдельно от кода. Какая от этого польза, мы поймем несколько позже, а сейчас обсудим технические приемы, используемые для решения этой задачи.