При написании процедуры или функции Delphi в ассемблерном коде, какие регистры должны быть сохранены и восстановлены до исходного значения в конце процедуры?
При вызове другой процедуры Delphi или функция из (встроенного) кода сборки, Что я могу ожидать, что эта другая функция делать с регистрами? Какие регистры будут восстановлены до их первоначальных значений, а какие нет?
(Очевидно, один и тот же ответ применим к обоим вопросам)
Я предполагаю, что соглашение о вызовах по умолчанию Delphi. Я знаю, что EAX
используется для 32-битных возвращаемых значений. И, глядя на код asm в SysUtils.pas, кажется, что EBX
, ESI
и EDI
выдвигаются и восстанавливаются, но другие - нет. Я не могу найти никаких документов по этому поводу.
Три первых аргумента функции приведены в EAX
, EDX
и ECX
соответственно. Дополнительные аргументы помещаются в стек. Для метода объекта указатель Self
всегда является (невидимым) первым параметром. Результат должен быть в EAX
. Для функций, возвращающих длинные строки, параметр (invisible) last функции является указателем на результирующую строку (которая сама по себе является указателем на первый символ строки).
EBX
нельзя изменять (если вы не восстановите его до завершения процедуры / функции), а также ESP
, EBP
, ESI
или EDI
. (1) Отличное введение в встроенный ASM Delphi можно было найти здесь: http://www.delphi3000.com/articles/article_3766.asp
Я не знаю, актуальна ли документация, но вам следует взглянуть на Использование встроенного ассемблерного кода (только для Win32) на Embarcardero Wiki:
Цитата:
В целом, правила использования регистров в ассемблерном операторе такие же, как и во внешней процедуре или функции. Оператор asm должен сохранять регистры EDI, ESI, ESP, EBP и EBX, но может свободно изменять регистры EAX, ECX и EDX. При входе в оператор asm EBP указывает на текущий кадр стека, а ESP указывает на вершину стека. За исключением ESP и EBP, оператор ассемблера не может ничего предполагать о содержимом регистра при входе в оператор.