標籤:指標 彙編 棧 寄存器 作業系統
由於作業系統中的共用性質,所以,寄存器也就成為了各個進程或者過程共用資源的一種。那麼發生過程 調用的時候,如果調用者要用到一個寄存器裡面的值,但是這個寄存器的內容很可能在被調用者運行過程中修改,那麼我們就要在被調用過程執行之前,對該寄存器裡面的內容進行保護,以至於不會出錯,寄存器的保護規則也是因為程式的不可再現性而存在的。
在IA32上,實行了一個統一的寄存器保護規則。首先,我們要看一下,電腦中有多少個比較重要的寄存器
(偷偷懶我就不寫寄存器前面的百分比符號了O(∩_∩)O)
eax 這個寄存器屬於調用者儲存寄存器,通常用來儲存一些函數的返回值
edx ecx這兩個也是屬於調用者儲存寄存器,並且 屬於通用寄存器,可以隨意儲存資料,沒有 什麼特定的 限制。
ebx edi esi這三個寄存器屬於被調用者儲存寄存器。通常來說edi 和 esi可能會儲存一些被調用函數的參數。
這裡要說明一下一個概念,就是我很疑惑的,什麼叫做調用者儲存寄存器,什麼叫做被調用者儲存寄存器。
兩者的區別,我覺得可以用下面的圖示來說明一下。
上面的圖示說明 ,寄存器按照規則被分類了,左面的三個寄存器是調用者負責儲存,右邊三個寄存器是被調用者負責儲存。也就是說,在程序呼叫的時候,如果被調用者程式會覆蓋左邊三個寄存器的內容,那麼,如果這三個寄存器內容在程序呼叫結束之後還要用到沒調用過程之前的那個數值的話,就要有人在程序呼叫發生之前儲存這個寄存器裡面的數值,但是由誰來儲存呢?只能由調用者去儲存,也就是說,被調用者是不會管你這裡面有什麼重要的資料的,他拿過來就用,但是調用者如果需要這裡面的資料,就要自己提前儲存。說的再直白一點,就是寄存器是任何程式都可以隨便用的,但是裡面資料的儲存工作就是有責任人的。左邊三個寄存器的責任人是調用者,右邊三個寄存器的責任人是被調用者。
我覺得這樣理解是正確的,如果我恰好理解反了,還希望大家給我指出來。
還有兩個比較重要的寄存器:
esp是棧頂指標的寄存器
ebp是基底位址暫存器
學過彙編的人會知道,在進行程序呼叫的時候,主要是用程式棧來支援過程的調用,並且機器也會利用棧來儲存一些參數。這樣一來,在程序呼叫中,上面兩個寄存器裡面的資料就變得相當重要。在一個程序呼叫的時候,必須要儲存舊的ebp裡面的資料,並且初始化的時候也需要movl ebp esp這樣的指令將兩個棧指標初始化一下,之後,esp會隨著過程的調用進行擴充增長,在程序呼叫結束的時候,要有一些指令進行恢複和清理工作,把棧恢複成這次調用之前的樣子。那麼我們就要進行如下 兩個指令mov ebp esppopl ebp第一條指令是清理工作,也就是釋放棧空間,把棧頂指標移動到基址指標的地方,因為在call指令執行的時候,調用者會把被調用過程完成之後下一條指令的地址壓入棧中。所以,在popl將舊的基地址恢複之後,esp也就向棧低移動 到了下一條指令執行的地址那裡。這樣一來調用完成之後的恢複和清理工作也就結束了。