Цитата Сообщение от captain cobalt
Вот именно. Адрес таблицы должен быть фиксированным.
"Относительно меня или вас?" (Ц)

Он прекрасно фиксированный относительно каждой программы
с которой КОПИЯ данной таблицы скомпонована. Понимаешь,
КОПИЯ. Много их. Таблиц этих. Каждой программе -- своя. И ещё
одна на библиотеку, СВОЯ КОПИЯ. Поэтому её адрес известен,
как известен адрес любой процедуры в своей программе.

Это не особо мешает, если таблица одна единственная.
Но что если таблиц две или больше?
Кто выбирает адреса для таблиц?
Ассемблер. При компиляции.

Что если независимые разработчики выберут пересекающиеся адреса?
Тогда две программы не загрузить одновременно. Или две
библиотеки. Потому пишите релоцируемый код. И таблица
сама релоцируемой получится. КОПИЯ таблицы то-есть,
локальная. А потом, когда всё будет загружено, информация
из ГЛАВНОЙ ТАБЛИЦЫ, которая связана с программой функции
которой вызываются через эту таблицы, должна быть скорпирована
во ВТОРИЧНЫЕ ТАБЛИЦЫ, которые используются сторонними
программами для вызова функций из библиотеки или программы
с которой связана ГЛАВНАЯ ТАБЛИЦА. Что тут непонятного?

На оффтопиках действительно применяется этот способ. Таблица вместе с кодом лепится в одно целое. Но там команды CALL относительные, поэтому всегда показывают в таблицу независимо от того по какому адресу загрузили модуль. Но на Z80 нет относительных CALL, только короткие JR.
Я только что описал, как работает заменитель "относительных CALL". Именно это он и позволяет. Вызов по адресу известному
относительно собственного программного модуля.