0

I want to use 'rbx' and 'rcx' registers in my function and before using them, I want to save them. Since it's 2 registers, I want to know which way is better? push them one-by-one or reserve stack (16-byte) and copy each value into the stack and ...

Way1:

FUNC:
        push rbx
        push rcx

        ...
        ...

        pop rbx
        pop rcx

Way2:

   sub    rsp, 16
   mov    QWORD [rsp], rbx
   mov    QWORD [rsp+8], rcx

   ...
   ...

   mov    rbx, QWORD [rsp]
   mov    rcx, QWORD [rsp+8]
   add    rsp, 16

The second way has more source code (size), but I'm talking about CYCLE. When I just want to use a register, it's clear that I must use push but what should I do for 2 or more registers like this? Push them one-by-one or stack reserve and ...?

I heard that push is: 1 - reserve stack 2 - copy the register value into the reserved stack

and also pop is: 1 - copy the value into the register 2 - restore stack

So for 2 or more registers, I can do it my self without multi reserve and restore (stack)

Nick Decroos
  • 153
  • 1
  • 8
ELHASKSERVERS
  • 195
  • 1
  • 10
  • Gcc uses push. I assume those guys have verified that it’s the best way (or at least no worse). The processor has special optimizations for updating the stack pointer. – prl Dec 20 '19 at 08:45
  • 2
    Are you familiar with the typical calling conventions? Generally, rcx doesn’t need to be preserved. if you’re calling this function from your own assembly function, you can use whatever convention you want, but I find it makes life easier to follow the normal convention in most cases. – prl Dec 20 '19 at 08:48

1 Answers1

2

x86 CPUs since about Pentium-M have a stack engine that handles the RSP updates, making push/pop single-uop like mov store/load. That's why GCC uses push/pop unless you use -mtune=pentium3 or something.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847