20

I'm writing a function in x86 assembly that should be callable from c code, and I'm wondering which registers i have to restore before i return to the caller.

Currently I'm only restoring esp and ebp, while the return value is in eax.

Are there any other registers I should be concerned about, or could I leave whatever pleases me in them?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
bobbaluba
  • 3,584
  • 2
  • 31
  • 45
  • 1
    There is no general rule -- you'll have to consult the C compiler's documentation to see what it expects. – Jerry Coffin Mar 07 '12 at 14:14
  • I'm pretty sure Jerry's right, and it depends on the calling convention; if memory serves, there are different "standard" conventions on Windows, Posix etc. Which compiler are you using? – Tomer Gabel Mar 07 '12 at 14:18
  • gcc. I found this searching http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions (see exit sequence), but it doesn't say anything about the registers, just that they should be restored to a state expected by the caller. – bobbaluba Mar 07 '12 at 14:26

3 Answers3

22

Using Microsoft's 32 bit ABI (cdecl or stdcall or other calling conventions), EAX, EDX and ECX are scratch registers (call clobbered). The other general-purpose integer registers are call-preserved.

The condition codes in EFLAGS are call-clobbered. DF=0 is required on call/return so you can use rep movsb without a cld first. The x87 stack must be empty on call, or on return from a function that doesn't return an FP value. (FP return values go in st0, with the x87 stack empty other than that.) XMM6 and 7 are call-preserved, the rest are call-clobbered scratch registers.

Outside of Windows, most 32-bit calling conventions (including i386 System V on Linux) agree with this choice of EAX, EDX and ECX as call-clobbered, but all the xmm registers are call-clobbered.


For x64 under Windows, you only need to restore RBX, RBP, RDI, RSI, R12, R13, R14, and R15. XMM6..15 are call-preserved. (And you have to reserve 32 bytes of shadow space for use by the callee, whether or not there are any args that don't fit in registers.) xmm6..15 are call-preserved.
See https://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_x64_calling_convention for more details.

Other OSes use the x86-64 System V ABI (see figure 3.4), where the call-preserved integer registers are RBP, RBX, RSP, R12, R13, R14, and R15. All the XMM/YMM/ZMM registers are call-clobbered.

EFLAGS and the x87 stack are the same as in 32-bit conventions: DF=0, condition flags are clobbered, and x87 stack is empty. (x86-64 conventions return FP values in XMM0, so the x87 stack registers always need to be empty on call/return.)


For links to official calling convention docs, see https://stackoverflow.com/tags/x86/info

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Necrolis
  • 25,836
  • 3
  • 63
  • 101
14
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

For details see "Software optimization resources" by Agner Fog. Calling conventions are described in this pdf.

Evgeny Kluev
  • 24,287
  • 7
  • 55
  • 98
1

if you are unsure about the registers' situation, these instructions below could save the day easily.

PUSHA/PUSHAD -- Push all General Registers
POPA/POPAD -- Pop all General Registers

These instructions push and pop the general purpose and SI/ESI , DI/EDI registers in certain order.

The order for PUSHA/PUSHAD instruction is as follows.

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

And the order for POPA/POPAD instruction is as follows. (in reverse order)

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

*** The ESP value is discarded instead of loaded into ESP.

Tanzer
  • 300
  • 1
  • 10
  • 3
    The `POPA` and `POPAD` instructions don't actually pop the (E)SP register! Also please correct an error on `POPAD`: you forgot the EBX register. Furthermore you are wrongly stating that these instructions touch the *segment registers*! – Sep Roland Aug 09 '15 at 21:13