任務是動態的概念,程序的執行狀態。程序給的解釋就是靜態的,例如桌面上放了個五子棋的程序。 小程序
爲了保存任務的狀態,並在下次從新執行程序的時候恢復它們,每一個任務都應當擁有一個額外的內存區域記錄相關的信息,這叫作任務狀態段(TSS)。 安全
這個地方寫這個與點不合適,由於麼有徹底看懂。 測試
下面簡單在串一下。 spa
在前面簡單介紹過,保護模式的尋址http://my.oschina.net/u/1185580/blog/182241 .net
這裏詳細囉嗦下。 調試
1.保護模式下的段是找的上圖這種的描述符 每一個描述符的大小是8個字節=2個雙字 code
2.描述符有 全局描述符表、局部描述符秒、任務描述符表、中斷、門;描述符都在全局描述符中定義 blog
3.上圖中的s=0 系統 type=1100(門);權限間的切換 ip
0010(ldt 也就是局部描述符); 內存
1001(任務ltr不忙);
1011(任務ltr忙)
=1 代碼、數據段(type(第一位也就是11位)=0數據段;=1代碼段)
下面是一個簡單的描述符的定義
;建立1#描述符,這是一個數據段,對應0~4GB的線性地址空間 mov dword [ebx+0x08],0x0000ffff ;基地址爲0,段界限爲0xFFFFF mov dword [ebx+0x0c],0x00cf9200 ;粒度爲4KB,存儲器段描述符
4.進入保護模式後,根據選擇子獲得 基地址+偏移量 而後檢查權限、檢查界限=安全的檢查
5.暫且看的是,代碼數據段當即加載過去了;
若是是局部描述表要先獲得局部描述符的,lldt中,而後獲得局部描述符表信息;(<64KB大小)
若是是任務描述符則就應該是後面的偏移量是沒有用的
這些是記錄任務當前運行的狀態
這裏說明下調用門的格式:
31--------------------16-15----------------------------0
選擇子 偏移量15-0
31--------------------16-15-14-13-12-11----8-7-4----0
偏移量 P |DPL| 0 |TYPE| 0 參數個數
調用門實施特權級的控制轉移,可使用jmp far指令,也可使用 call far 指令
使用jmp far指令能夠將控制經過門轉移到比當前特權級別高的代碼段,但不改變當前的特權級別;
若是使用call會改變當前特權級的CPL。1.堆棧的請求要求是必須與當前的特權級請求一致,哪意味着堆棧的切換
2.數據段的請求權限》=當前的權限
3.代碼段的請求權限 同級別或者依從【(權限《=當前)纔可使用】
type 11-8 10位是C位
系統不容許高的權限轉移到底的權限中。
call 段內轉移 esp入棧
call 段間轉移 cs、esp依次入棧
當沒有特權級變化的時候,cal,jmp均可以進入任務門。
*這樣的處理權限的轉換問題
當特權級切換的時候哪?
LABEL_TSS: DD 0 ; Back DD 0 ; 0 級堆棧,現處於0級 esp的值 DD 0x00000020 ;堆棧選擇子 DD 0 ; 1 級堆棧 DD 0 ; DD 0 ; 2 級堆棧 DD 0 ; DD 0 ; CR3 DD 0 ; EIP DD 0 ; EFLAGS DD 0 ; EAX DD 0 ; ECX DD 0 ; EDX DD 0 ; EBX DD 0 ; ESP DD 0 ; EBP DD 0 ; ESI DD 0 ; EDI DD 0 ; ES DD 0 ; CS DD 0 ; SS DD 0 ; DS DD 0 ; FS DD 0 ; GS DD 0 ; LDT 就是0 DW 0 ; 調試陷阱標誌 DW $ - LABEL_TSS + 2 ; I/O位圖基址 截取後16位 DB 0ffh ; I/O位圖結束標誌 TSSLen equ $ - LABEL_TSS
;目的是分頁的練習 ;時間 2013-12-14 下午 週六 [org 0x7c00] [bits 16] ldt_description equ 0x00007F00 mov ax,cs mov ds,ax call show_style ;設置顯示模式 主要是清屏 ;計算GDT所在的邏輯段地址 mov eax,[pgdt+0x02] ;獲得描述符的基地址 xor edx,edx mov ebx,16 div ebx mov ds,eax ;令DS指向該段以進行操做 mov ebx,edx ;段內起始偏移地址 ;建立0#描述符,它是空描述符,這是處理器的要求 ;建立1#描述符,這是一個數據段,對應0~4GB的線性地址空間 mov dword [ebx+0x08],0x0000ffff ;基地址爲0,段界限爲0xFFFFF mov dword [ebx+0x0c],0x00cf9200 ;粒度爲4KB,存儲器段描述符 ;建立保護模式下初始代碼段描述符 mov dword [ebx+0x10],0x7c0001ff ;基地址爲0x00007c00,界限0x1FF mov dword [ebx+0x14],0x00409800 ;粒度爲1個字節,代碼段描述符 ;創建保護模式下的堆棧段描述符 ;基地址爲0x00007C00,界限0xFFFFE mov dword [ebx+0x18],0x7c00fffe ;粒度爲4KB mov dword [ebx+0x1c],0x00cf9600 ;創建保護模式下的顯示緩衝區描述符 mov dword [ebx+0x20],0x80007fff ;基地址爲0x000B8000,界限0x07FFF mov dword [ebx+0x24],0x0040920b ;粒度爲字節 ;爲了測試句不斷選擇子,大小就8個字節也就是一個ldt mov eax,ldt_description shl eax,16 or eax,0x00000007 mov dword [ebx+0x28],eax ;基地址爲0,段界限爲8 mov dword [ebx+0x2c],0x00408200 ;粒度爲4KB,存儲器段描述符 mov eax, LABEL_TSS ;TSS段基地址 shl eax,16 or eax,TSSLen-1 mov dword [ebx+0x28],eax mov dword [ebx+0x2c],0x00408900 ;========================================================= ;初始化描述符表寄存器GDTR ;由於上面吧數據段地址改了因此這利用代碼段 mov word [cs:pgdt],55 ;描述符表的界限(總字節數減一) n*8-1; lgdt [cs:pgdt] in al,0x92 ;南橋芯片內的端口 or al,0000_0010B out 0x92,al ;打開A20 cli ;保護模式下中斷機制還沒有創建,應 ;禁止中斷 mov eax,cr0 or eax,1 mov cr0,eax ;設置PE位 ;如下進入保護模式... ... jmp dword 0x0010:protect_loader-0x7C00;16位的描述符選擇子:32位偏移 ;hlt ;程序終止 ;===================showStyle============================= show_style: ;設置顯示方式 mov ah,0x00 mov al,0x03 int 10h ret ;========================================================= [bits 32] protect_loader: xor eax,eax mov eax,0000_0000_00100_000B ;#4 顯示段 mov es,eax mov byte[es:0x00],'H' mov byte[es:0x02],'E' mov byte[es:0x04],'L' mov byte[es:0x06],'L' mov byte[es:0x08],'O' mov byte[es:0x0a],',' mov byte[es:0x0c],'O' mov byte[es:0x0e],'S' mov eax,0000_0000_00001_000B ;#1數據段 4G mov es,eax xor ebx,ebx mov ebx,ldt_description; 獲得偏移地址 mov dword [es:ebx+0x00],0x7c0001ff mov dword [es:ebx+0x04],0x00409800 ;拼湊一個lldt的選擇子 xor eax,eax mov ax,0000_0000_00101_000B ;第五個描述符的位置 lldt ax ;加載lldt ;hlt ;jmp dword 0x0004:ldt_loader-0x7c00 mov eax,0000_0000_00110_000B ;#6 TSS段 ltr ax xor esp,esp ;esp設置爲0 jmp dword ax:0 hlt ;程序終止 ;---------------------------------------------------------------- ldt_loader: ;這裏是局部全局變量的加載 xor eax,eax mov eax,0000_0000_00100_000B ;#4 顯示段 mov es,eax mov byte[es:0x00+0xa0],'L' mov byte[es:0x02+0xa0],'L' mov byte[es:0x04+0xa0],'D' mov byte[es:0x06+0xa0],'T' hlt; LABEL_TSS: DD 0 ; Back DD 0 ; 0 級堆棧,現處於0級 esp的值 DD 0x00000020 ;堆棧選擇子 DD 0 ; 1 級堆棧 DD 0 ; DD 0 ; 2 級堆棧 DD 0 ; DD 0 ; CR3 DD 0 ; EIP DD 0 ; EFLAGS DD 0 ; EAX DD 0 ; ECX DD 0 ; EDX DD 0 ; EBX DD 0 ; ESP DD 0 ; EBP DD 0 ; ESI DD 0 ; EDI DD 0 ; ES DD 0 ; CS DD 0 ; SS DD 0 ; DS DD 0 ; FS DD 0 ; GS DD 0 ; LDT 就是0 DW 0 ; 調試陷阱標誌 DW $ - LABEL_TSS + 2 ; I/O位圖基址 截取後16位 DB 0ffh ; I/O位圖結束標誌 TSSLen equ $ - LABEL_TSS ;--------------數據段-------------------------------------------- pgdt dw 0 dd 0x00007e00 ;GDT的物理地? times 510-($-$$) db 0 db 0x55 ;引導識別標示 db 0xaa
上面 首先實例化了 1.全局段描述符表GDT;lgdt
2.而後跳轉進入了保護模式
3.實例化了LDT的描述符表 經過4G的數據段
4.加載lldt、加載了ltr
5.最後根據ltr的這個選擇子進入了,lldt中的選擇子 0 (固然也能夠直接跳轉加載lldt的選擇子)
效果以下