Какие регистры восстанавливаются после вызова функции x86 в c?

Я пишу функцию в сборке x86, которая должна быть вызвана из c-кода, и мне интересно, какие регистры мне нужно восстановить, прежде чем я вернусь к вызывающему. В настоящее время я только восстанавливаю esp и ebp, а возвращаемое значение - в eax. Есть ли какие-либо другие регистры, о которых я должен беспокоиться, или могу ли я оставить все, что угодно мне?

Ответ 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).

Ответ 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.