外贸网站contact,互联网广告营销公司,公司网站建设北京,asp.net网站建设项目实战资料叶函数是指不调用其他函数#xff0c;也不改变任何非易失性寄存器的函数2。叶函数通常是一些简单的操作#xff0c;如数学运算或逻辑判断。叶函数的特点是可以通过模拟返回来展开#xff0c;即不需要保存或恢复寄存器的状态。 非叶函数是指调用其他函数或改变非易失性寄存器…叶函数是指不调用其他函数也不改变任何非易失性寄存器的函数2。叶函数通常是一些简单的操作如数学运算或逻辑判断。叶函数的特点是可以通过模拟返回来展开即不需要保存或恢复寄存器的状态。 非叶函数是指调用其他函数或改变非易失性寄存器的函数。非叶函数通常是一些复杂的操作如循环或递归。非叶函数的特点是需要使用静态数据来注释以便在处理异常时恢复寄存器的状态。 非易失性寄存器是指在断电后仍能保持其内容不变的寄存器。非易失性寄存器通常用于保存一些重要的数据或状态例如程序计数器、栈指针、返回地址等。 易失性寄存器是指在断电后会丢失其内容的寄存器。易失性寄存器通常用于保存一些临时的数据或操作数例如通用寄存器、浮点寄存器、向量寄存器等。 非易失性寄存器和易失性寄存器在函数调用时有不同的约定。一般来说被调用函数需要保护非易失性寄存器的值即在使用之前将其压入栈中在返回之前将其弹出栈中。而被调用函数可以自由地使用易失性寄存器而不需要保存或恢复它们的值。这样可以减少函数调用时的开销和复杂度 函数调用时需要遵循以下两条规则
调用者保存规则在函数调用之前调用者必须保存任何临时t0–t6 和 a0–a7寄存器这些寄存器在调用后仍然需要。在调用后它必须在使用它们之前恢复这些寄存器。被调用者保存规则在被调用者改变任何保留寄存器s0–s11 和 ra之前它必须保存这些寄存器。在返回之前它必须恢复这些寄存器。 上图给出一个非叶函数 f1 和一个叶函数 f2 的代码示例以及它们如何遵循这些规则。非叶函数是指调用其他函数的函数叶函数是指不调用其他函数的函数。
f1 保持 i 在 s4 和 x 在 s5f2 保持 r 在 s4。f1 使用了保留寄存器 s4、s5 和 ra所以它最初将它们压入栈中以遵循被调用者保存规则。它使用 t3 来保存中间结果 (a–b)这样就不需要为这个计算保留另一个寄存器。 在调用 f2 之前f1 将 a0 和 a1 保存到栈中以遵循调用者保存规则因为这些是非易失性寄存器f2 可能会改变它们而 f1 在调用后仍然需要它们。ra 改变了因为它被 f2 的调用覆盖了。虽然 t3 也是一个非易失性寄存器f2 可能会覆盖它但 f1 不再需要 t3所以不必保存它。 f1 然后将参数传递给 f2 在 a0 中进行函数调用并在 a0 中得到结果。f1 然后恢复 a0 和 a1因为它仍然需要它们。当 f1 完成时它将返回值放在 a0 中恢复寄存器 s4、s5、ra 和 sp并返回。f2 根据被调用者保存规则保存和恢复 s4和 sp。 仔细观察后可能会注意到 f2 没有修改 a1所以 f1 不需要保存和恢复它。然而编译器不能总是很容易地确定哪些非易失性寄存器可能在函数调用期间被干扰。因此一个简单的编译器总是让调用者保存和恢复任何它在调用后需要的非易失性寄存器。一个优化的编译器可以观察到 f2 是一个叶过程并可以将 r 分配给一个非易失性寄存器避免了保存和恢复 s4 的需要。下图显示了函数执行期间的栈情况。对于这个例子栈指针最初从 0xBEF7FF0C 开始。