The code you're showing is unoptimized. If you want to see good code, use -O2 or -O3. The purpose of unoptimized code is to work better with the debugger — optimized code can be harder on the debugger in finding where variables are (and when!).
pushq %rbp is part of function prologue, which is code that creates a stack frame aka an activation record. A stack frame represents the instantiation of a function or method, which happens at such time as when the function is invoked by some caller. A function can have zero, one, or more instantiations, the latter being the case during recursion; instantiated functions generally have stack frames.
However, when the function is trivial — in particular, it does not call another function (we may call this a leaf function) — then (depending on other factors per the ISA) it does not need a stack frame. This is another aspect that may make things more difficult for the debugger; so unless optimization is requested, a stack frame is created even by trivial functions that otherwise might not need one. (Some analysis, usually done as optimization, is also needed to determine whether stack frame is required or can be eliminated.)
The stack frame also has two forms: (1) where the stack pointer alone is used, and (2) where two pointers are used, a stack pointer and a frame pointer. The latter form tends to facilitate debugging, and some features of stack unwinding and/or exception throwing.
In the two-register stack frame form,
bp is the second register, and it is know as the frame pointer. In order to create a stack frame of this type, the callee's function prologue contains instructions that save the caller's
bp (frame pointer) using that push instruction. Now saved, the
bp register is taken over to become the callee's frame pointer by copying the current
sp into it. Next, the stack space for the callee is allocated by subtracting (as the stack grows down) a constant size (specific to that function) from the stack pointer,
A full frame for the callee is thus created. The callee may then store some of the other CPU registers holding caller values into its frame.
Upon exit, there is the opposite of the function prologue called the function epilogue, which releases the stack frame and restores the caller's registers (including the frame pointer). The final operation of the callee then is to return to the caller (using
ret), and the only thing left on the stack, the return address, is popped during transfer of control back to the caller.