寄存器的保護(hù)與恢復(fù)

字號:

由于計算機的硬件資源只有一套,當(dāng)子程序修改了寄存器的內(nèi)容后,返回到調(diào)用它的程序時,這些寄存器的內(nèi)容也就不會是調(diào)用子程序前的內(nèi)容。這樣,子程序修改寄存器內(nèi)容就可能變成了調(diào)用它的副作用,這種副作用常常會導(dǎo)致調(diào)用程序的出錯。為此,在編寫子程序時,除了能對作為入口和出口參數(shù)的寄存器進(jìn)行修改外,對其它寄存器的修改對調(diào)用程序來說都要是透明的,也就是說,在調(diào)用子程序指令的前后,除了作為入口和出口參數(shù)的寄存器內(nèi)容可以不同外,其它寄存器的內(nèi)容要保持不變。有時,也要求作為入口參數(shù)的寄存器內(nèi)容保持不變。
    在子程序中,保存和恢復(fù)寄存器內(nèi)容的主要方法是:在子程序的開始把它所用到的寄存器壓進(jìn)棧,在返回前,再把它們彈出棧。這樣編寫的好處是該子程序可以被任何其它程序來調(diào)用。在調(diào)用指令前,不需要保存寄存器,在調(diào)用指令后,也無需恢復(fù)寄存器。
    利用堆棧來保存和恢復(fù)寄存器內(nèi)容方法的一般形式如下:
    XXXXXPROC
    PUSHREG1
    …
    PUSHREGn;把子程序要使用的寄存器壓棧,REGi代表某個寄存器
    …
    …
    …;子程序的處理功能語句
    POPREGn;把前面壓棧的寄存器彈出,注意它們的次序
    …
    POPREG1
    RET
    XXXXXENDP
    例7.2就是一個在子程序中利用堆棧來保存和恢復(fù)寄存器內(nèi)容的例子。利用堆棧來實現(xiàn)此項功能時,應(yīng)注意以下幾點:
    、用堆棧保存和恢復(fù)寄存器的內(nèi)容,要注意堆?!跋冗M(jìn)后出”的操作特點;
    、通常情況下不保護(hù)入口參數(shù)寄存器的內(nèi)容,當(dāng)然,也可以根據(jù)事先的約定而對它們加以保護(hù);
    、如果用寄存器帶回子程序的處理結(jié)果,那么,這些寄存器就一定不能加以保護(hù);
    、整個子程序的執(zhí)行幾乎肯定要改變標(biāo)志位,可用PUSHF和POPF來保護(hù)和恢復(fù)標(biāo)志位,但一般在子程序中不保護(hù)標(biāo)志位,除非有此特殊需要