<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 一、段描述符的分類 在上一篇博文中已經說過,為了使用段,我們必須要創建段描述符。80X86中有各種各樣的段描述符,下圖展示了它們的分類。 [![段描述符的分類](https://box.kancloud.cn/2016-02-29_56d3a8fbe3f06.jpg "段描述符的分類")](http://img.blog.csdn.net/20160109212457811) 看了上圖,你也許會說:天啊,怎么這么多段描述符啊!我可怎么記住呢?![哭泣的臉](https://box.kancloud.cn/2016-02-29_56d3a8f857ea0.jpg) 別擔心,我會在以后的博文中,跟隨原書的作者,為您逐步介紹。我們的學習是循序漸進的,所以不要求一下子掌握所有東西。我們的原則是:用到什么學什么。我們今天的重點是“存儲段描述符”。 # 二、段描述符的通用格式[1] 段描述符是GDT和LDT中的一個數據結構項,用于向處理器提供有關一個段的位置、大小以及訪問控制的狀態信息。每個段描述符的長度是8個字節,含有3個主要字段: - 段基地址 - 段限長 - 段屬性 段描述符通常由編譯器,鏈接器,加載器或者操作系統來創建,但絕不是應用程序。 下圖給出了所有類型的段描述符的一般形式。 [![捕獲](https://box.kancloud.cn/2016-02-29_56d3a8fc12783.jpg "捕獲")](http://img.blog.csdn.net/20160109212502690) ? ### 1.段限長字段Limit 用于指定段的長度。處理器會把段描述符中兩個段限長字段組合成一個20位的值,并根據顆粒度標志G來指定段限長Limit值的實際含義。 如果G=0,則Limit值的單位是B,也就是說Limit的范圍可以是1B到1MB; 如果G=1,則Limit值的單位是4KB,也就是說Limit的范圍可以是4KB到4GB。 根據段類型字段TYPE中的段擴展方向標志E,處理器可以以兩種不同的方式使用Limit。 E=0:表示向上擴展的段(簡稱上擴段),邏輯地址中的偏移值范圍可以從0到Limit; E=1:表示向下擴展的段(簡稱下擴段),邏輯地址中的偏移范圍可以從Limit到0xFFFF(當B=0時)或者0xFFFF_FFFF(當B=1時)。關于B位,后面將解釋。 ### 2.基地址字段Base 該字段定義在4GB線性地址空間中一個段的字節0所處的位置。也許你覺得這句話不好理解,我們換一種說法:對于一個邏輯地址,如果段內偏移為0,那么這個邏輯地址對應的線性地址就是Base;如果段內偏移為X,那么這個邏輯地址對應的線性地址就是Base+X; 段基地址可以是0~4GB范圍內的任意地址(這同實模式不同,實模式下段基地址要求16字節對齊),但是,為了讓程序具有最佳性能,還是建議段基地址對齊16字節邊界。 ### 3.段類型字段TYPE 該字段用于指定段或者門(Gate)的類型、說明段的訪問種類以及段的擴展方向。該字段的解釋依賴于描述符類型標志S;TYPE字段的編碼對代碼段、數據段或者系統描述符都不同。 ### 4.描述符類型標志S S=0:表示存儲段描述符。所謂“存儲段”,就是存放可由程序直接進行訪問的代碼和數據的段。說白了,存儲段就是代碼段或者數據段。 S=1:表示系統描述符。 ### 5.描述符特權級字段DPL 用于指明描述符的特權級。特權級范圍從0(最高)到3(最低)。DPL字段用于控制對段的訪問。 ### 6.段存在標志P 用于指出一個段是在內存中(P=1)還是不在內存中(P=0). ### 7.D/B(默認操作數大小/默認棧指針大小和上界限) 對于代碼段,此位稱為“D”位;對于棧段,此位稱為“B”位。我們在后文會說。 ### 8.顆粒度標志G 該字段用于確定段限長字段Limit值的單位。 如果G=0,則Limit值的單位是B; 如果G=1,則Limit值的單位是4KB; 注意:這個字段不影響段基地址的顆粒度,基地址的顆粒度總是以字節為單位。 ### 9.可用和保留位 L位(就是上圖灰色的那個位):是64位代碼段標志,保留此位給64位處理器使用。目前,我們將此位置“0”即可。 AVL:是軟件可以使用的位,通常由操作系統來用,處理器并不使用它。 ? # 三、數據段描述符[1] 當S=1且TYPE字段的最高位(第2個雙字的位11)為0時,表明是一個數據段描述符。 下圖是數據段描述符的格式。 [![數據段描述符](https://box.kancloud.cn/2016-02-29_56d3a8fc2de1e.jpg "數據段描述符")](http://img.blog.csdn.net/20160109212506980) ### 1.B位(默認棧指針大小和上界限) 對于棧段(由SS寄存器指向的數據段)來說,該位用來指明隱含堆棧操作(如PUSH、POP或CALL)時的棧指針大小。 B=0:使用SP寄存器 B=1:使用ESP寄存器 同時,B的值也決定了棧的上部邊界。 B=0:棧段的上部邊界(也就是SP寄存器的最大值)為0xFFFF; B=1:棧段的上部邊界(也就是ESP寄存器的最大值)為0xFFFF_FFFF. ### 2.A位(已訪問) 用于表示一個段最近是否被訪問過(準確地說是指明從上次操作系統清零該位后一個段是否被訪問過)。 當創建描述符的時候,應該把這位清零。之后,每當該段被訪問時(準確地說是處理器把這個段的段選擇符加載進段寄存器時,也許你不懂這句話,沒有關系,現在忽略就可以了。)它就會將該位置“1”;對該位的清零是由操作系統負責的,通過定期監視該位的狀態,就可以統計出該段的使用頻率。當內存空間緊張時,可以把不經常使用的段退避到硬盤上,從而實現虛擬內存管理。 ### 3.W位(可寫) 指示段的讀寫屬性。 W=0:段不允許寫入,否則會引發處理器異常中斷; W=1:允許寫入。 ### 4.E位(擴展方向) E=0:表示向上擴展的段(簡稱上擴段),邏輯地址中的偏移值范圍可以從0到Limit; E=1:表示向下擴展的段(簡稱下擴段,通常是棧段),邏輯地址中的偏移范圍可以從Limit到0xFFFF(當B=0時)或者0xFFFF_FFFF(當B=1時)。 # 四、代碼段描述符[1] 當S=1且TYPE字段的最高位(第2個雙字的位11)為1時,表明是一個代碼段描述符。 下圖是代碼段描述符的格式。 [![代碼段描述符](https://box.kancloud.cn/2016-02-29_56d3a8fc4a479.jpg "代碼段描述符")](http://img.blog.csdn.net/20160109212514896) ### 1.D位(默認操作數大小) 用于指出該段中的指令引用有效地址和操作數的默認長度。 D=0:默認值是16位的地址和16位或者8位的操作數; D=1:默認值是32位的地址和32位或者8位的操作數; 說明:指令前綴0x66可以用來選擇非默認值的操作數大小,指令前綴0x67可以用來選擇非默認值的地址大小。 ### 2.A位(已訪問) 與數據段描述符中的A位相同。 ### 3.R位(可讀) R=0:代碼段不可讀,只能執行。 R=1:代碼段可讀,可執行。 也許有人會問,當R=0時,既然代碼段不可讀,那處理器怎么從里面取指令執行呢?事實上,這里的R屬性并非針對處理器,而是用來限制程序的行為。當常數或者靜態數據被放在了一個ROM中時,就可以使用一個可讀可執行的代碼段,然后通過使用帶CS前綴的指令,就可以讀取代碼段中的數據。 注意: - 在保護模式下,代碼段是不可寫的。 - 堆棧段必須是可讀可寫的數據段。 ### 4.C位(一致性) C=0:表示非一致性代碼段。這樣的代碼段可以被同級代碼段調用,或者通過門調用; C=1:表示一致性代碼段。可以從低特權級的程序轉移到該段執行(但是低特權級的程序仍然保持自身的特權級)。 注意:所有的數據段都是非一致性的,即意味著它們不能被低特權級的程序或過程訪問。然而與代碼段不同,數據段可以被更高特權級的程序或過程訪問,而無需使用特殊的訪問門。 有關特權級和特權級檢查我們以后再討論,這里對上面的概念了解即可,不用深究。 **** 最后,補充一張圖表,也是引用自趙炯的《Linux內核完全剖析》。 ? [![表4-3](https://box.kancloud.cn/2016-02-29_56d3a8fc6b0c4.jpg "表4-3")](http://img.blog.csdn.net/20160109212519317) **** **參考資料:** [1]:趙炯,《Linux內核完全剖析》,機械工業出版社. 4.3.4節
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看