Используя 32-битный ABI от Microsoft (cdecl
или stdcall
или другие соглашения о вызовах), EAX
, EDX
и ECX
- это чистые регистры (с прерыванием вызова).Остальные целочисленные регистры общего назначения сохраняются при вызове.
Коды условий в EFLAGS являются замкнутыми при вызове.При вызове / возврате требуется DF = 0, поэтому вы можете использовать rep movsb
без cld
.Стек x87 должен быть пустым при вызове или при возврате из функции, которая не возвращает значение FP.(Возвращаемые значения FP идут в st0
, при этом стек x87 пуст, кроме этого.) XMM6 и 7 сохраняются при вызове, остальные - это незаполненные регистры при вызове.
За пределами Windows большинство 32-соглашения о вызовах битов (в том числе i386 System V в Linux) согласуются с этим выбором EAX, EDX и ECX в качестве системного вызова, но все регистры xmm являются системными вызовами.
Для x64 под Windows требуется только восстановить RBX
, RBP
, RDI
, RSI
, R12
, R13
, R14
и R15
.XMM6..15 сохраняются по вызову.(И вам нужно зарезервировать 32 байта теневого пространства для использования вызываемым абонентом, независимо от того, есть ли какие-либо аргументы, которые не помещаются в регистры.) Xmm6..15 сохраняются при вызове.
См. https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention для получения более подробной информации.
Другие операционные системы используют x86-64 System V ABI (см. Рисунок 3.4) , где целочисленные регистры с сохранением вызова - RBP
, RBX
,RSP
, R12
, R13
, R14
и R15
.Все регистры XMM / YMM / ZMM являются замкнутыми при вызове.
EFLAGS и стек x87 такие же, как в 32-разрядных соглашениях: DF = 0, флаги условий помечены, а стек x87 пуст.(Соглашения x86-64 возвращают значения FP в XMM0, поэтому регистры стека x87 всегда должны быть пустыми при вызове / возврате.)
Для ссылок на официальные документы соглашений о вызовах,см https://stackoverflow.com/tags/x86/info