system V (x86_64 ) abi calling conventions: should caller-saved variables be saved in recursive calls (even if they are not changed)?

Viewed 83

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.

0 Answers
Related