Search code examples
assemblyx86-64calling-convention

What happens to %rax after an empty return statement in a void function?


My understanding is that, if a void function is executed without a return statement, then %rax will still store whatever is returned from the previous non-void function.

That is, if:

int a(int param){
    return param;
}

void b(){
}

int main(){
    a(5);
    b();
    return 1;
}

Then after main finishes execution but before returning, the value stored in %rax will be 5.

My question is, what happens if b has an empty return statement? That is,

void b(){
    return;
}

Does that clear out %rax? Or does %rax still retain its previous value still?


Solution

  • then %rax will still store whatever is returned from the previous non-void function.

    No, your understanding is wrong.

    When RAX doesn't hold a return value (void or FP functions), it's a call-clobbered register like RCX or RSI for example. Read the calling convention docs or look at compiler output.

    And BTW, an explicit return statement vs. reaching the } at the bottom is completely irrelevant. (Except that falling off the end of a non-void function is UB, and some compilers will compile that to a ud2 illegal instruction.)

    Then after main finishes execution but before returning, the value stored in %rax will be 5.

    That is 100% implementation detail; a compiler can do anything it wants with registers within a function, like use RAX to evaluate non-function-call expressions. The calling convention only nails down the boundaries between functions.