0

I have the following code:

#include <x86intrin.h>

int main() {
    return __rdtsc();
}

And I tried to compile on my machine (Intel i7-6700 CPU) and objdump

g++ -Wall test_tsc.cpp -o test_tsc -march=native -mtune=native -O0 -std=c++20
objdump -M intel -d test_tsc > test_tsc.O0

Then in test_tsc.O0:

0000000000401122 <main>:
  401122:   55                      push   rbp
  401123:   48 89 e5                mov    rbp,rsp
  401126:   0f 31                   rdtsc  
  401128:   48 c1 e2 20             shl    rdx,0x20
  40112c:   48 09 d0                or     rax,rdx
  40112f:   90                      nop
  401130:   5d                      pop    rbp
  401131:   c3                      ret    
  401132:   66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
  401139:   00 00 00 
  40113c:   0f 1f 40 00             nop    DWORD PTR [rax+0x0]

What do push rbp and mov rbp,rsp do? It seems like they were for saving the stack pointer but then there isn't really a function call. If g++ consider __rdtsc() a function call, then would there be something like call afterward?

Thanks.

HCSF
  • 2,387
  • 1
  • 14
  • 40
  • 2
    For various reasons, the function prologue/epilogue are often emitted unconditionally. – o11c Dec 16 '21 at 03:29
  • 2
    compile this with -O2, and you'll end up with rdst followed by ret (which is what you expect). If you compile non optimised debug build (as you are doing here), the compiler will 'de-optimise' code by copying register values into known memory locations (which a debugger is then able to access easily). The result is a bunch of mov's that make very little sense. Just use -O2 or -O3. – robthebloke Dec 16 '21 at 03:32
  • 1
    Because you used `-O0`, of course, where `-fno-omit-frame-pointer` is the default. RBP frame pointer setup / teardown happens even in an empty function (unlike clang where leaf functions may still omit the frame pointer). https://godbolt.org/z/cEPGssYac. It's not "for saving the stack pointer", you can't usefully save/restore the stack pointer on the stack. – Peter Cordes Dec 16 '21 at 05:47

1 Answers1

0

rbp is the base pointer, not the stack pointer. The base pointer is used for backtrace during debugging but it is not necessary for actually running.

It is preserved through function calls so with -O3 only the expected assembly is generated:

main:
        rdtsc
        salq    $32, %rdx
        orq     %rdx, %rax
        ret