进入保护模式(五)简单任务的安装

一、任务

       任务是动态的概念,程序的执行状态。程序给的解释就是静态的,例如桌面上放了个五子棋的程序。

       为了保存任务的状态,并在下次重新执行程序的时候恢复它们,每个任务都应当拥有一个额外的内存区域记录相关的信息,这叫做任务状态段(TSS)。

       这个地方写这个与点不合适,因为么有完全看懂。

       下面简单在串一下。

二、保护模式下的段式寻址

       在前面简单介绍过,保护模式的寻址http://my.oschina.net/u/1185580/blog/182241

       这里详细啰嗦下。

  

      1.保护模式下的段是找的上图这种的描述符 每个描述符的大小是8个字节=2个双字

      2.描述符有 全局描述符表、局部描述符秒、任务描述符表、中断、门;描述符都在全局描述符中定义

      3.上图中的s=0 系统 type=1100(门);权限间的切换

                                       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的选择子)

效果如下

 

 

转载于:https://my.oschina.net/findurl/blog/186078

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值