system V (x86_64 ) abi 调用约定:调用者保存的变量是否应该保存在递归调用中即使它们没有改变?

问题描述

假设我想实现一个对给定范围内的数字求和的函数

int sumRange(int start,int end);

这是我想出的实现:(AT&T asm 语法)

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

请注意,%edi%esi 都是调用者保存的寄存器。 %edisumRange 的不同递归层次的帧之间发生变化,因此必须保存在 Pre-Call 中,但 %esi 不是在递归调用中进行了更改 - 因此代码仍然可以在不保存该寄存器的情况下工作。

问题是:这段代码是否符合 System V 约定?

我认为没有:
该约定不考虑被调用函数实际更改的寄存器(据我所知)。
因此,我们需要假设所有调用者保存的寄存器在函数调用后都可能发生变化。

此外,即使我们在递归调用后不使用 %esi,我也希望 %esi整个 sumRange.

的范围

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)