Я пишу функцию в сборке x86, которая должна быть вызвана из c-кода, и мне интересно, какие регистры мне нужно восстановить, прежде чем я вернусь к вызывающему. В настоящее время я только восстанавливаю esp и ebp, а возвращаемое значение - в eax. Есть ли какие-либо другие регистры, о которых я должен беспокоиться, или могу ли я оставить все, что угодно мне?
Какие регистры восстанавливаются после вызова функции x86 в c?
Ответ 1
Использование 32-битный ABI файл Microsoft, EAX
, EDX
и ECX
являются регистрами нуля, все остальное должно быть сохранено.
Для x64 под Windows, Microsoft говорит, вам нужно восстановить RBX
, RBP
, RDI
, RSI
, R12
, R13
, R14
и R15
.
Для x64 под любым System V и AMD64 (см. рисунок 3.4), его RBP
, RBX
, RSP
, R12
, R13
, R14
и R15
(они кажутся странными, потому что ядро использует один набор регистров, а код userland использует другой набор, это указано в приложении A документации ABI).
Ответ 2
32-bit: EBX, ESI, EDI, EBP
64-bit Windows: RBX, RSI, RDI, RBP, R12-R15, XMM6-XMM15
64-bit Linux,BSD,Mac: RBX, RBP, R12-R15
Подробнее см. "Ресурсы оптимизации программного обеспечения" от Agner Fog. Соглашения о вызовах описаны в этом pdf.
Ответ 3
Если вы не уверены в ситуации с регистрами, эти инструкции ниже могут легко сэкономить день.
PUSHA/PUSHAD - нажмите все общие регистры
POPA/POPAD - поместить все общие регистры
Эти инструкции нажимают и вызывают общие цели и регистры SI/ESI, DI/EDI в определенном порядке.
Порядок для команды PUSHA/PUSHAD выглядит следующим образом.
Opcode Instruction Clocks Description
60 PUSHA 18 Push AX, CX, DX, BX, original SP, BP, SI, and DI
60 PUSHAD 18 Push EAX, ECX, EDX, EBX, original ESP, EBP ESI, and EDI
И порядок для инструкции POPA/POPAD выглядит следующим образом. (в обратном порядке)
Opcode Instruction Clocks Description
61 POPA 24 Pop DI, SI, BP, SP, BX, DX, CX, and AX
61 POPAD 24 Pop EDI, ESI, EBP, ESP(***),EBX, EDX, ECX, and EAX
*** Значение ESP отбрасывается вместо загрузки в ESP.