Проблема в том, что ваши данные находятся в сегменте данных, а ваш код - в текстовом сегменте.Компоновщик настроен так, чтобы требовать перемещаемого кода, что означает, что вы не можете использовать абсолютный адрес, поскольку вы не можете знать абсолютный адрес до времени выполнения.
Чтобы использовать перемещаемый код, вам необходимо получить доступ к data_items
каксмещение от указателя инструкций, rip
.
_main:
movl $0, %edi
leaq data_items(%rip), %rax
movl (%rax,%rdi,4), %eax
Инструкция leaq
получает адрес data_items
, используя смещение указателя инструкций, которое можно вычислить во время соединения.Затем инструкция movl
использует этот адрес в качестве базы для загрузки данных.Обратите внимание, что я использовал rdi
в адресации.Когда вы пишете в edi
, старшие 32 бита rdi
автоматически очищаются, поэтому это будет работать без изменений, пока значение в edi
не подписано.Вы можете использовать edi
и eax
, но это приведет к обрезанию адресов, использующих более 32 бит, и скомпилированный код будет больше, поскольку размер адреса по умолчанию составляет 64 бита.