Say I want to implement a function for summing the numbers in a given range:
int sumRange(int start, int end);
And this is the implementation I came up with: (AT&T asm syntax)
sumRange:
cmp %edi, %esi
jl return_zero #jump if start > end
#Pre-Call:
push %edi
inc %edi
# push %esi
call sumRange
#Post-Call:
# pop %esi
pop %edi
add %edi, %eax
ret # return start + sumRange(start+1, end)
return_zero:
xor %eax, %eax
ret # return 0
Note that both %edi and %esi are caller-saved register. %edi changes between the frames of the different recursive levels of sumRange so it must be saved in the Pre-Call, but %esi is not changed in the recursive call - so the code will still work without saving that register.
The question is: does this code meet the System V convention?
I think that it does not:
The convention does not consider what registers the called function actually changes (as far as I have found).
Therefore we are required to assume all caller-saved registers might change after a function-call.
Also, even if we do not make use of %esi after the recursive call, I would expect %esi to have it's proper value for the entire scope of sumRange.