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

Почему ассемблерный код Delphi ведет себя иначе в исключительных ситуациях, чем чистый Pascal?

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

 

При написании ассемблерного кода для Delphi на платформе Win64 возникают сложности с обработкой исключений, что может привести к тому, что программа завершится аварийно. В данной статье мы рассмотрим причины этой проблемы и предложим решение.

Проблема

Вот пример кода на чистом Pascal:

procedure Test;
var
  i2: Integer;
begin
  i2 := 0;
  i2 := 0 div i2;
end;

Когда этот код компилируется, Delphi генерирует соответствующий ассемблерный код. Вот пример ассемблерного кода, сгенерированного компилятором Delphi:

procedure Test;
asm
  push rbp
  sub rsp,$10
  mov rbp,rsp
  mov [rbp+$0c],$0000007b
  mov [rbp+$08],$00000000
  mov eax,[rbp+$0c]
  cdq
  idiv dword ptr [rbp+$08]
  mov [rbp+$08],eax
  lea rsp,[rbp+$10]
  pop rbp
end;

Если попытаться вызвать процедуру Test и обработать исключение в блоке try..except, программа может аварийно завершиться из-за ошибки unwind-exception.

Почему это происходит?

Виной всему является то, что ассемблерный код не содержит метаданных, необходимых для обработки исключений в системе Structured Exception Handling (SEH) Windows. SEH — это механизм, используемый Windows для обработки исключений. Он требует дополнительных данных, которые должны быть сгенерированы компилятором и указаны в секциях PE файла. В случае чистого Pascal-кода компилятор генерирует эти данные автоматически, но когда мы пишем ассемблерный код вручную, эти данные могут отсутствовать.

Решение

Для того чтобы ассемблерный код корректно обрабатывал исключения, необходимо добавить соответствующие метаданные вручную. Это можно сделать с помощью MASM (Microsoft Macro Assembler), который предоставляет псевдо-инструкции для управления стеком и генерации дополнительной информации.

Вот пример, как можно написать ассемблерный код с использованием MASM:

_text SEGMENT
Test PROC FRAME
   push rbp
.pushreg rbp
   sub rsp, 010h
.allocstack 010h
   mov rbp, rsp
.setframe rbp, 0
.endprolog
  mov dword ptr [rbp+0Ch], 7Bh
  mov dword ptr [rbp+08h], 0
  mov eax, dword ptr [rbp+0Ch]
  cdq
  idiv dword ptr [rbp+08h]
  mov dword ptr [rbp+08h], eax
  lea rsp, [rbp+10h]
  pop rbp
  ret
Test ENDP
_text ENDS
END

Этот код использует следующие псевдо-инструкции MASM:

  • .pushreg rbp: Указывает, что регистр rbp будет использоваться для сохранения и восстановления стекового фрейма.
  • .allocstack 010h: Указывает, что на стеке будет выделено 16 байт.
  • .setframe rbp, 0: Указывает, что стековый фрейм начинается с регистра rbp и имеет длину 0 байт.
  • .endprolog: Определяет конец пролога.

Интеграция с Delphi

Для интеграции ассемблерного кода с Delphi можно использовать следующий подход:

  1. Скомпилировать ассемблерный код с помощью MASM: sh ml64 /c test.asm Это создаст объектный файл test.obj.

  2. Включить объектный файл в Delphi проект:
    {$L test.obj}
    procedure Test; external;

  3. Вызвать процедуру Test и обработать исключения:
    try
    Test;
    except
    WriteLn('Handled!');
    end;

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

Заключение

Обработка исключений в ассемблерном коде на платформе Win64 требует специального подхода, так как необходимо добавить метаданные, необходимые для SEH. Использование MASM и соответствующих псевдо-инструкций позволяет решить эту проблему и обеспечить корректное поведение программы при возникновении исключений.

Дополнительные ресурсы

Надеюсь, эта статья поможет вам понять проблему и предложенные решения для обработки исключений в ассемблерном коде Delphi на платформе Win64.

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

Статья посвящена проблеме обработки исключений при написании ассемблерного кода для Delphi на платформе Win64 и предлагает решение с использованием MASM для добавления необходимых метаданных.


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

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




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


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


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-03-22 18:24:54/0.0034041404724121/0