Delphi не генерирует прологи или эпилоги для функций, имеющих без аргументов и объявленных с регистром соглашения о вызовах. Если вам нужны функции без прологов, объявите их как функции с нулевым аргументом, функции регистрации вызовов. Также пропустите блок begin
- end
и перейдите прямо к сборке.
procedure SomeAssembly; // register; (implied)
asm
// ...
end;
Поскольку вы фактически лжете о природе функций, вызывать их может быть сложно. Если вы реализовали функцию так, как будто она получила параметры и использовали другое соглашение о вызовах, то вам нужно убедиться, что компилятор знает об этом на сайте вызовов. Для этого объявите указатель на функцию, который отражает «реальный» тип вашей функции вместо объявленного типа. Например, если ваша функция действительно является функцией stdcall с двумя аргументами, объявите что-то вроде этого:
type
TSomeAssemblyFunc = function (Arg1: Integer; Arg2: PAnsiChar): Boolean; stdcall;
var
SomeAssemblyProc: TSomeAssemblyProc;
Теперь назначьте эту переменную так, чтобы она указывала на вашу функцию:
SomeAssemblyProc := TSomeAssemblyProc(@SomeAssembly);
if SomeAssembly(2, 'foo') then ...
Помимо пропуска пролога и эпилога, компилятор сгенерирует неверную инструкцию RET
для этой функции (из-за разного соглашения о вызовах), поэтому вам нужно будет убедиться, что вы произнесете ret 8
в своем коде вместо того, чтобы дать команду компилятора по умолчанию ret
.
Найти длину пролога Delphi тривиально, если у вас есть работающий отладчик:
- Установить точку останова в начале функции.
- Вызовите функцию.
- Когда отладчик останавливается в точке останова, переключитесь в представление CPU.
- Посмотрите на инструкции, из которых состоит пролог.
- Подсчитать количество байтов, отображаемых рядом с этими инструкциями.