## 8.3 保護和I/O(Protection and I/O)
有兩種機制用于I/O保護:
1、? FLAGS里的IOPL字段定義了使用I/O指令的特權級。
2、? TSS段里的I/O許可位圖定義了使用I/O地址空間的特權級。
這些機制只在保護模式下工作,包含虛擬8086模式。在實模式中他們不會起作用。在實模式中,I/O空間沒有任何保護。任何子程序可執行I/O指令。任意I/O端口都是可以被I/O指令尋址的。
### 8.3.1 I/O 特權級(I/O Privilege Level)
處理I/O的指令應該被限制執行,但不在特權級0執行I/O指令也是需要的。所以,處理器用了標志寄存器里的兩位來存儲I/O的特權級(IOPL)。IOPL定義了要執行I/O指令所需要的特權級。
以下指令只有當CPL <= IOPL時才可以執行:

這些指令被稱作“敏感指令”,因為他們對I/O敏感的。
為了執行敏感指令,子程序必須執行在至少小于或等于(數值上)IOPL(CPL <= IOPL)的特權級。任何沒有足夠特權級的程序執行I/O指令時將引起通用保護異常。
因為每個任務都有自已的標志寄存器,每個程序都有不同的IOPL。一個任務如果主要任務是完成I/O操作的話(設備驅動程序)可以讓IOPL為3,所以他的任何子程序都可以執行I/O。其它一些程可以把IOPL設成0或1,只讓特權級高的子程序可以執行I/O。
一個任務只有通過POPF指令才能改變IOPL。但是,這樣的改變是特權級的。只有在特權級0執行的程序才可以改變IOPL。不夠特權級的程如果試圖更改IOPL的話,不會產生任何異常,而IOPL只是保持不變。
一條POPF指令可以用來副加的開中斷和關中斷。但是,通過POPF來改變IF標志位也是特權級的。一個想通過POPF指令來改變IF標志的程序,必須要執行在到少IOPL的特權級上(數值上小于或等于)。同樣,不夠特權級的試圖更改并不會產生任何異常,而IF只是保持不變。
### 8.3.2 I/O 許可位圖(I/O permission Bit Map)
直接指定處理器I/O地址空間的I/O指令是IN,INS,OUT,OUTS。80386可以有選擇性的把一些I/O地址空間訪問設成陷阱。允計這樣做的數據結構是在TSS段(請看圖8-2)中的I/O 許可位圖(I/O Permission Bit Map)I/O許可位圖是一個位向量。位圖的大小是可變的,這個值存放在TSS段中。處理器通過TSS中的位圖基址來定位這個位圖。I/O位圖基址是一個16位寬的字段,包含了I/O許可位圖的偏移。位圖的上限也是TSS段的上限。
在保護模式下,當遇到一條I/O指令時(IN,INS,OUT,或OUTS),處理器首先檢查是否CPL<=IOPL。如果是的話,I/O操作可以繼續。如果不是的話,處理器檢查I/O許可位圖。(在虛擬8086模式,處理器不管IOPL而直接查看位圖,參看第15章)
位圖中的每一位都對應著一個I/O端口字節地址。例如,端口41的位可以在I/O位圖基址+5,位偏移1,處找到。處理器會檢測I/O指令訪問到的每個字節,以看是否允許訪問。例如,一個雙字操作,將測試4位,對應著4個連續的字節地址空間。如果任一個測試是置位的,處理器引發一個通用保護異常。如果所有的測試都有為0,I/O操作被允許。
沒有必要為所有的I/O地址設置I/O許可位圖。沒有被覆蓋到的I/O地址空間,將被假設該位圖對應位已設置為1。例如,如果TSS界限等于I/O位圖基址+31的話,前256的端口被映射。對于更大的端口號作的I/O操作將引起異常。
如果I/O映射位圖基址大于或等于TSS界限的話,TSS段則沒有I/O許可位圖,所以只要當CPL>IOPL時,所有的I/O操作將引起異常。
因為I/O許可位圖在TSS段中,不同的任務有不同的映射位圖。操作系統可以通過修改一個任務的TSS段中的I/O許可位圖,來為某個任務分配端口,

- 第一章 80386介紹
- 1.1 該手冊的組織結構
- 1.2 其他文獻
- 第二章 編程基本模型
- 2.1 存儲器組織和段
- 2.2 數據類型
- 2.3 寄存器
- 2.4 指令格式
- 2.5 操作數選擇
- 2.6 中斷和異常
- 第4章 系統寄存器
- 4.1 系統寄存器 (System Registers)
- 4.2 系統指令 (System Instructions)
- 第五章 內存管理
- 5.1 分段地址轉換(Segment Translation)
- 5.2 分頁地址轉換(Page Translation)
- 5.3 混合分段和分頁地址轉換(Combining Segment and Page Translation)
- 第六章 內存管理
- 6.1 為什么要保護(Why Protection?)
- 6.2 80386保護機制概述(Overview of 80386 Protection Mechnaisms)
- 6.3 段級保護(Segment-Level Protection)
- 6.4 頁級保護(Page-Level Protection)
- 6.5 混合分頁和分段保護(Combining Page and Segment Protection)
- 第7章 多任務(Multitasking)
- 8.1 I/O 尋址(I/O Addressing)
- 7.1 任務狀態段(Task State Segment)
- 7.3 任務寄存器(Task Register)
- 7.4 任務門描述符(Task Gate Descriptor)
- 7.5 任務切換(Task Switching)
- 7.6 任務鏈(Task Linking)
- 7.7 任務尋址空間(Task Address Space)
- 第8章 輸入 輸出
- 8.2 I/O 指令(I/O Instructions)
- 8.3 保護和I/O(Protection and I/O)
- 第9章 異常和中斷(Exceptions and Interrupts)
- 9.1 識別中斷(Identifying Interrupts)
- 9.2 允許和禁止中斷(Enabling and Disabling Interrupts)
- 9.3 同時發生的中斷和異常的優先級(Priority Among Simultaneous Interrupts and Exceptions)
- 9.4 中斷描述符表(Interrupt Descriptor Table)
- 9.5 IDT 描述符(IDT Descriptors)
- 9.6 中斷任務和中斷子程序(Interrupt Tasks and Interrupt Procedures)
- 9.7 出錯碼(Error Code)
- 9.8 異常條件(Exception Conditions)
- 9.9 異常總結(Exception Summary)
- 9.10 出錯碼總結(Error Code Summary)
- 第10章 初始化(Initialization)
- 10.1 復位后處理器狀態(Processor State After Reset)
- 10.2 實模式初始化(Software Initialization for Real-Address Mode)
- 10.3 切換到保護模式(Switching to Protected Mode)
- 10.4 保護模式初始化(Software Initialization for Protected Mode)
- 10.5 初始化示例
- 10.6 TLB測試
- 第十四章 80386實地址模式
- 14.1 物理地址構成
- 14.2 寄存器和指令
- 14.3 中斷和異常處理
- 14.4 進入和離開實地址模式
- 14.6 實地址模式異常
- 14.7 與8086的不同
- 14.8 與80286實地址模式的不同