What registers must be preserved by an x86 function?

后端 未结 3 1911
猫巷女王i
猫巷女王i 2020-11-29 11:09

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.

Curr

相关标签:
3条回答
  • 2020-11-29 11:38

    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.

    0 讨论(0)
  • 2020-11-29 11:42
    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.

    0 讨论(0)
  • 2020-11-29 11:43

    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

    0 讨论(0)
提交回复
热议问题