I've generated a few simple programs using the compiler explorer. Why does eax always get set to zero before the stack pops rbp? Is it standard to clear the registers before exiting?
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 1
mov DWORD PTR [rbp-8], 1
add DWORD PTR [rbp-4], 1
mov eax, DWORD PTR [rbp-4]
mov DWORD PTR [rbp-8], eax
mov eax, 0 <--------------------------?
pop rbp
ret
For reference, I am using x86-64 gcc 12.1
CodePudding user response:
No, it's not standard. You don't "clear" registers per-se, you always set them to some value. Sometimes that value is 0.
In C and C99, there's an implicit return 0;
at the bottom of main()
. EAX is the return-value register in all mainstream x86 calling conventions, including your x86-64 System V. Zeroing EAX implements that return 0;
, and wouldn't be there if the function wasn't called main
.
(Or if your source includes an explicit return 0;
of course; you forgot to include that in your question, or even link it as part of your Godbolt link; use the "share" button to make a shortlink or better a full link.)
In C , falling off the end of a non-void
function without a return
statement is undefined behaviour. The implicit return 0 at the end of main counts, so renaming it would make it UB for that path of execution to be reached, i.e. for the function to be called.
In C, it's only UB if the caller uses a return value from a function that fell off the end, because of C history: it existed for a while before void
was added, so there was historic code that had functions declared like foo(int x)
with an implicit int return value, but actually they didn't return anything and the caller didn't read the return value.
So anyway, renaming an int main()
to int foo()
without adding a return statement will give your function undefined behaviour in C , and with optimization enabled GCC won't emit any instructions at all for it, not even a ret
.
(It will of course also print a warning, at least with -Wall
. You should definitely enable -Wall
while playing around with compiler output, as things the compiler thinks are worth warning about are often related to weird asm. And on Godbolt, look for any red in the bottom left of the asm output pane, showing the number of warnings. Click on it to open a new pane with that.)