Ассемблерные вставки

b

Спецификация синтаксиса ассемблерных вставок в среде Delphi

Ассемблерная вставка в Delphi реализуется через конструкцию asmend, которая строго следует синтаксису Borland Turbo Assembler (TASM). Ключевое отличие от внешних ассемблерных модулей: вставка не требует отдельной компиляции — код на ассемблере обрабатывается непосредственно компилятором Delphi как часть процедуры или функции. Материал вставки размещается между ключевыми словами без дополнительных директив сегментации. Каждый оператор завершается точкой с запятой. Допускаются только команды процессора x86 (архитектура IA-32) — использование инструкций SSE/AVX возможно, но требует явного указания префиксов.

Регистровая модель и соглашение о вызовах

При работе с ассемблерными вставками внутри функций Delphi действует жесткое соглашение о распределении регистров:

Компилятор Delphi автоматически генерирует пролог и эпилог для процедуры, содержащей ассемблерный блок. Манипуляции с регистрами внутри asm/end не должны нарушать целостность стека — каждое изменение EBP или ESP должно быть обратно симметричным к моменту завершения блока. Для передачи дополнительных параметров через стек используется смещение относительно EBP.

Материал и ограничения при работе с памятью

Внутри ассемблерной вставки запрещено использовать динамические строки Delphi (AnsiString, WideString) напрямую — управление ссылками на них требует вызова специальных intrinsic-функций компилятора через директивы, выполняемые вне ассемблерного контекста. Для работы с массивами или записями (record) необходимо передавать указатель через регистр или стек, используя адресную арифметику. Материал данных, на который ссылается вставка, должен располагаться в сегменте данных приложения — прямой доступ к глобальным переменным возможен через их символьные имена. Компилятор подставляет фактические адреса на этапе линковки. Дифференциация от альтернатив (например, Intel C++ Compiler для вставок __asm): Delphi не поддерживает вложенные комментарии и макросы внутри ассемблерного блока, а также не допускает использование локальных меток с точкой.

Процесс генерации команд и стандарты выравнивания

Компилятор Delphi при обработке ассемблерной вставки не выполняет оптимизацию перестановки инструкций — каждая команда занимает строго свою позицию. Однако он принудительно выравнивает начало блока по границе 4 байт (для версий до 2010 года) или 16 байт (начиная с Delphi XE и позднее), что критично для инструкций, требующих выровненных операндов (например, MOVDQA). Качество итогового машинного кода целиком зависит от разработчика: компилятор не вставляет префиксы блокировки (LOCK) для многопоточности — их необходимо добавлять вручную к атомарным операциям. Стандартным требованием к промышленному коду является явная очистка регистров после завершения вставки, если они не входят в callee-save слот (EAX, ECX, EDX).

Технические различия с ассемблерными модулями (файлы .asm)

При выборе между вставкой и внешним ассемблерным модулем необходимо учитывать следующие спецификации:

  1. Генерация объектного файла: вставка не требует отдельного файла .obj — код встраивается непосредственно в машинный код функции Delphi, что ускоряет сборку, но усложняет отладку (отсутствие символов для отладчика в стиле TD32).
  2. Контроль типов: в ассемблерной вставке компилятор проверяет только синтаксис инструкций, но не типы операндов — приведение указателей и работа с размером данных (BYTE, WORD, DWORD) ложится на разработчика.
  3. Поддержка макросов: в отличие от отдельного модуля, где доступны макроподстановки TASM/MASM, вставка ограничена прямыми командами и не поддерживает REPT, EQU и т.д.
  4. Совместимость с 64-битной архитектурой: начиная с Delphi 2010 (версия 14.0) ассемблерные вставки полностью удалены при компиляции в режиме Win64 — для 64-битных приложений требуется использовать исключительно внешние ассемблерные библиотеки или переходить на Pure Pascal.

Тестирование и контроль целостности вставок

Верификация корректности ассемблерной вставки выполняется через визуальный анализ листинга (опция компилятора $O- и отображение инструкций в CPU-окне отладчика). Стандарты качества в промышленной разработке (ISO 26262, MISRA для embedded) требуют документирования каждого регистра, изменяемого внутри блока, и подтверждения отсутствия side-эффектов на глобальные переменные. Практическое тестирование включает прогон с избыточным количеством итераций для выявления ошибок переполнения стека или неправильного выравнивания. Рекомендуется использовать ассемблерные вставки только в критических по производительности участках (криптографические примитивы, кодеки, низкоуровневый ввод-вывод), где выигрыш в тактах процессора превышает 20% по сравнению с эквивалентом на Delphi, подтверждённый профилированием не менее чем на трёх различных поколениях CPU семейства x86.

Добавлено: 27.04.2026