寄存器的保存与恢复

在产生函数调用时,有可能调用者使用了某个寄存器,被调用者也使用了这个寄存器并对修改了其中的值。如果调用结束后调用者还需要使用先前这个寄存器中的值,此时就会导致调用者的状态遭到破坏。所以在函数调用时需要对这个寄存器中的值进行保存,同时函数返回时再把它恢复到调用前的状态

由于这种数据结构具有记忆功能,也就是当你将某个元素压入栈中之后,再进行出栈此时出栈时的元素还是你先前压入栈中的元素。所以通常使用来对寄存器进行保存与恢复。首先将寄存器中的值压入到中进行保存,然后才能对它们进行修改,最后再将之前保存在中的值逐个恢复到寄存器中。

下面代码分别把ax,bx这两个寄存器保存在栈中:

push(ax);
push(bx);

保存过程:

把栈中的值逐个恢复到寄存器中:

pop(bx);
pop(ax);

恢复过程:

这里要注意的是出栈和入栈的顺序是相反的,因为此时栈顶是之前bx的值,所以在恢复时需要先把栈顶的值弹出到bx,然后再把下一个值弹出至ax,这样就把值与寄存器对应起来了。

并不是所有的寄存器都需要保存与恢复,根据约定把寄存器中的一部分划分为被调用者保存调用者保存

  • 被调用者保存

    被调用者来负责这组寄存器的保存与恢复。由于任何一个函数都是一个被调用者,因为函数总是被调用后才会运行,因此可以得出任何一个函数在修改这组寄存器时都需要对它们进行保存与恢复

    例如函数P调用函数Q,在Q被执行时,Q首先将这组寄存器中它需要修改的部分寄存器压入中进行保存,最后在返回时再由Q负责再把栈中保存的值弹出这些寄存器中进行恢复。

  • 调用者保存

    除了被调用者保存栈指针(sp)以外的其他寄存器被称为调用者保存寄存器。由于任何一个函数都是一个被调用者,因此可以得出任何一个函数在修改这组寄存器时都不需要对它们进行保存与恢复

    例如函数P调用函数Q,在Q被执行前,P首先将这组寄存器中它不希望在Q返回时发生改变的部分寄存器压入中进行保存,最后Q返回后由P负责把栈中保存的值弹出这些寄存器中进行恢复。

results matching ""

    No results matching ""