Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Ошибка "Generating PIC, but reference is not PIC-safe" при использовании ассемблера в Delphi и Pascal

Delphi , Синтаксис , Assembler

 

Введение в проблему

При работе с ассемблерными вставками в Delphi и Free Pascal (Object Pascal) разработчики иногда сталкиваются с ошибкой "Generating PIC, but reference is not PIC-safe". Эта ошибка возникает при попытке компилятора сгенерировать позиционно-независимый код (PIC), когда используются ссылки, несовместимые с этим требованием.

Причины ошибки

Ошибка появляется в следующих ситуациях: - Использование абсолютных адресов в ассемблерных вставках - Попытка получить адрес метки или переменной способом, несовместимым с PIC - Неправильное обращение к сегментным регистрам в 64-битном коде

Решение проблемы

1. Использование RIP-относительной адресации

Как правильно указано в ответе, для 64-битного кода следует использовать RIP-относительную адресацию:

procedure Example;
label
  MyLabel;
begin
  asm
    lea MyLabel(%rip), %rax  // Правильный способ в 64-битном коде
    // ... остальной код
    MyLabel:
  end;
end;

2. Альтернативное решение - избегание прямого доступа к сегментным регистрам

В современных 64-битных системах сегментные регистры обычно не используются так, как в 16-битном или 32-битном режиме. Вместо прямого доступа к ним можно использовать другие методы.

Пример кода без сегментных регистров:

procedure SafeMemoryAccess;
var
  Data: array[0..255] of Byte;
begin
  // Доступ к памяти без явного использования сегментных регистров
  for var i := 0 to High(Data) do
    Data[i] := i;
end;

3. Использование встроенных функций компилятора

Delphi и Free Pascal предоставляют встроенные функции для работы с указателями, которые совместимы с PIC:

procedure SafePointerExample;
var
  P: Pointer;
begin
  P := @SomeProcedure;  // Встроенный оператор получения адреса
  // ... использование указателя
end;

Пример исправленного кода

Вернемся к исходному примеру и исправим его:

procedure kernel_gdt_initialize;
var
  tempRec: x64_gdt_descriptor;
  CodeSegmentSelector: Word;
begin
  // Инициализация GDT
  gdt.offset := QWord(@gdtEntry);
  gdt.size := SizeOf(gdtEntry) - 1;

  // Заполнение GDT
  kernel_gdt_set_entries; // вынесем в отдельную процедуру

  tempRec := gdt;

  asm
    // Загрузка GDT
    lgdtq [tempRec]

    // Переход на новый сегмент кода
    mov $0x08, %eax
    push %rax
    lea .Lret_point(%rip), %rax
    push %rax
    retq
  .Lret_point:

    // Обновление сегментных регистров
    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %ss
  end;
end;

Рекомендации по работе с ассемблером в Object Pascal

  1. Избегайте глобальных меток - используйте локальные метки (начинающиеся с .L)
  2. Используйте RIP-относительную адресацию в 64-битном коде
  3. Минимизируйте ассемблерные вставки - используйте их только там, где это действительно необходимо
  4. Проверяйте совместимость кода с PIC/PIE (позиционно-независимый код/исполняемый файл)

Заключение

Ошибка "Generating PIC, but reference is not PIC-safe" возникает при несовместимости ассемблерного кода с требованиями позиционно-независимого кода. Основное решение - использование RIP-относительной адресации в 64-битном коде. В большинстве случаев можно избежать прямого манипулирования сегментными регистрами, используя высокоуровневые конструкции Pascal.

При работе с низкоуровневыми операциями в Delphi/Free Pascal всегда проверяйте совместимость вашего кода с современными требованиями безопасности и переносимости.

Создано по материалам из источника по ссылке.

Ошибка "Generating PIC, but reference not PIC-safe" в ассемблерных вставках Delphi/Free Pascal, связанная с несовместимостью позиционно-независимого кода (PIC) и некорректного использования адресации, решается через RIP-относительные ссылки, избегание се


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Assembler ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-13 21:21:57/0.0063788890838623/0