堆疊的切換

2021-07-15 12:42:22 字數 2121 閱讀 5823

當目標**執行完畢,需要返回控制權給原**時,將產生返回控制權行為。返回控制權行為,比轉移控制權行為簡單得多。因為,一切條件已經在交出控制權之前準備完畢,返回時僅需出棧就行了。

1、 

near call的返回

近呼叫情況下,段不改變,即 cs 不改變,許可權級別不改變。從棧中pop返回位址到eip暫存器時,需進行 limit 的檢查。

2、 

直接控制權轉移的返回(

far call

或far jmp

直接轉移返回到相同許可權級別,發生跨段的返回,許可權不變。這時,cs 被從棧中 pop 出來的 cs 值載入進去,處理器會檢查 cpl 與這個 pop 出來的選擇子(calling procedure cs)中的rpl進行檢查,相等則屬相級返回。

3、 

利用各種門符進行向高許可權**轉移後的返回

★    檢查儲存在 called procedure stack

中的原calling procedure cs

rpl

域以確保是從高許可權向低許可權**返回。

★    原calling procedure cs及eip被pop到cs及eip 暫存器中。

★    若有引數時,called procedureesp需恢復棧結構(加上相應引數size)

★    原calling procedure ss及esp被pop到ss及esp暫存器中。

★    若有引數時,原calling procedure esp 需恢復結構(加上相應引數size)。

★    恢復原calling procedurecs後,將檢查每個segment selector(ds、es、fs及gs),假如資料段許可權高於cs,則被載入null segment selector。

作業系統必須至少建立乙個tss,4個許可權級別的堆疊結構(stack segment selector及stack pointer)必須被定義。

一、

堆疊及棧指標的許可權級別:

★    3 級:stack selector及stack pointer儲存在ss暫存器及esp 暫存器中

★    0、1及2級:相應的stack selector及stack pointer儲存在tss相應的域中。

二、當發生向高許可權級別**轉移時,發生堆疊的切換:

★    根據cpl**移時cpl改變)在tss得到相應級別的堆疊結構(ss及esp)

★    進行棧結構檢查,包括limit檢查、stack segment descriptor一系列的檢查後,stack selector

及stack pointer

載入到ss

及esp

暫存器。

★    將原來級別的(許可權低)stack selector及stack pointer壓入新的堆疊中(許可權高),這個過程是:載入新的ss及

esp時,先臨時儲存舊的ss及

esp,再將臨時儲存舊的ss及

esp壓入新的堆疊中。

★    若有引數,則壓入引數(引數個數定義在call gate中的param count域)

★    壓入返回位址(cs及eip)

★    若有錯誤碼,則壓入錯誤碼。

注意事項:

★    call gate 允許最多31個引數,在呼叫者的堆疊裡。發生切換時,將從呼叫者的堆疊裡複製到新的堆疊裡。

切換後堆疊結構圖:

calling procedure         called procedure

… …param1

param2

param3

… …

… …calling ss

calling esp

param1

param2

param3

calling cs

calling eip

... ...

… … 頂

0

踩 0

中斷發生時使用者堆疊和核心堆疊的切換

如果乙個中斷產生時任務正在使用者 中執行,那麼該中斷會引起cpu特權級從3到0的變化,此時cpu就會執行使用者態堆疊到核心態堆疊的切換操作。cpu會從當前任務的任務狀態段tss中取得新堆疊的段選擇符和偏移量。因為中斷服務程式在核心中,屬於0級特權級 所以48位的核心態堆疊指標會從tss的ss0和es...

任務核心態堆疊與使用者態堆疊之間的切換

在linux 0.12系統中,所有中斷服務程式都屬於核心 如果乙個中斷產生時任務正在使用者 中執行,那麼該中斷就會引起cpu特權級從3級到0級的變化,此時cpu就會進行使用者態堆疊到核心態堆疊的切換操作。cpu會從當前任務的任務狀態段tss中取得新堆疊的段選擇 在linux 0.12系統中,所有中斷...

堆,棧,堆疊的區別

乙個程式一般分為3段 text段,data段,bss段 text段 就是放程式 的,編譯時確定,唯讀,data段 存放在編譯階段 而非執行時 就能確定的資料,可讀可寫 就是通常所說的靜態儲存區,賦了初值的全域性變數和靜態變數存放在這個區域,常量也存放在這個區域 bss段 定義而沒有賦初值的全域性變數...