保护模式、段全局描述符表、段选择子以及相关工具

一开始的内存寻址就是单纯在一个物理的线性地址空间直接寻址,后来,技术发展了,内存大,搞出了内存分段机制。技术又发展了,空间更大了,就想搞多用户多任务操作系统。多用户多任务系统需要保证安全,不能出现—我是a,但我能直接修改b,c,d,e,f的数据,或者说,a程序可以直接读取b,c,d,e,f程序运行时的数据。从硬件层面提供一种策略—保护模式。

保护模式下寻址的核心数据结构:段描述符,段选择子

跨平台段描述符可视化工具(基于浏览器的工具,从某种意义上来讲,可不就是跨平台_ _):
请添加图片描述
请添加图片描述
工具位置:
https://gitee.com/YMQ_1314/linux_os_learn
描述符工具在util/gdt/gdt_generate.html
段选择子工具在util/gdt/segment_selector.html

一、内存分段机制

注:
1、我这里所讲的内存分段机制,不是在分页机制基础之上的分段存储管理方式。
2、讲得是16位模式下的寻址

1、内存分段机制的定义
内存分段(英语:Memory segmentation),一种电脑内存的管理技术,它将电脑的主内存分成许多区
段(segment或sections)。当处理器要进行内存寻址时,会使用一个数值,这个数值包括了某个区
段,以及偏移量(offset)。

2、内存分段机制下的寻址及其举例
请添加图片描述
请添加图片描述
请添加图片描述

! as86 ld86 汇编 链接
! 段寄存器 cs代码段寄存器,ds数据段寄存器,es附加段寄存器,ss堆栈段寄存器
! 物理线性地址 = 段寄存器中的值*16 + 偏移地址。
! 下边打印字符串 ds:si其具体地址就是 ds中的值*16 + si中的值(十进制,即我们数! 学中的1,2,3,4.....)。
! 假设在十六进制下, ds数据段 = 0x9000, si = 0x100,
! 那么其物理线性地址为0x90000 + 0x100 = 0x90100。 段地址无符号左移四位 + 偏移地址

INITSEG  = 0x9000

mov ax,#SETUPSEG
mov ds,ax
mov es,ax
call print_enter_wrap	! 打印回车换行
sub si,si
lea si,extend_memeory_size_title
call print_string

! 显示位于DS:SI处以NULL(0x00)结尾的字符串。
print_string: 
	lodsb
	and al,al
	jz fin
	call print_char   ! 显示al中的一个字符。
	jmp print_string
fin:
	ret

! 该子程序使用中断0x10的OxOE功能,以电传方式在屏幕上写一个字符。光标会自动移到下一个
! 位置处。如果写完一行光标就会移动到下一行开始处。如果已经写完一屏最后-行,则整个屏幕
! 会向上滚动一行。字符0x07 (BEL)、0x08 (BS)、OxOA(LF)和OxOD (CR)被作为命令不会显示。
! 输入:AL——欲写字符;BH——显示页号;BL——前景显示色(图形方式时)。
print_char:
	push ax
	push cx
	mov  bh,#0x00   !显示页面
	mov  cx,#0x01
	mov  ah,#0x0e
	int  0x10
	pop cx
	pop ax
	ret

extend_memeory_size_title:
	.ascii "extend memeory size: "
	db 0x00

二、保护模式及其寻址

百度百科定义:

保护模式,是一种80286系列和之后的x86兼容CPU操作模式。保护模式有一些新的特色,设计用来增强多工和系统稳定
度,像是 内存保护,分页 系统,以及硬件支援的 虚拟内存。大部分的现今 x86 操作系统 都在保护模式下运行,包
含 Linux、FreeBSD、以及 微软 Windows 2.0 和之后版本。

另外一种286和其之后CPU的运行模式是实模式,一种向前兼容且关闭了保护模式这些特性的CPU运行模式。用来让新的
芯片可以运行旧的软件。依照设计的规格,所有的x86 CPU都是在实模式下开机,来确保传统操作系统的向前兼容性。
在任何保护模式的特性可用前,他们必须要由某些程序手动地切换到保护模式。在现今的计算机,这种切换通常是由操
作系统在开机时候必须完成的第一件任务的一个。它也可能当CPU在保护模式下运行时,使用虚拟86模式来运行设计运
行在实模式下的代码。

保护模式与实模式相对应。在80286以前,CPU只有实时模式,地址总线有20位,而内存地址是16位,也就是最多能够
访问2^20=1M的内存空间。在80286及以后,内存地址改为16位或32位,至少可以访问到2^32=4G的内存空间。但为了
保证后续的CPU能够运行旧的CPU,只能保持向下兼容。因此,80286及以后的CPU首先进入实模式,然后通过切换机制
再进入到保护模式。

在保护模式下,当我们执行一个装载CS寄存器的指令的时候,段选择子(Segment Selector)被装入CS寄存器的可
见部分,同时CPU根据此选择子到相应的描述符表中(GDT或LDT)找到相应的段描述符并将其内容装载入CS寄存器的不
可见部分。随后CPU当需要通过CS的内容进行地址运算的时候,也仅仅引用不可见部分。
注:
1、讲得是32位模式下的寻址。
2、32位机器为保护模式。
3、64位机器为IA-32e模式。
4、16位寻址模式。即:寻址能力为1M;分段机制;每段不超过64kb。
5、x86处理器在内存中按小端顺序存放和检索数据,假设16进制数据0x12345678,那么
从0000号位置开始存放,数据越高位的内容放在内存编号越小的位置。

在16位模式下,程序可以自由地访问不允许它的内存位置,而且最大的寻址空间为1MB。可随着科技的发展,
硬件更新,有了32位机器。此时,它的寻址空间至少达到了4GB。寻址空间的增大,也为多用户多任务系统
的实现带来了可能,同时也产生了访问安全性的问题。

32位机也采用了段+偏移的模式来寻址。但与实模型不同的是,由于地址线和数据线宽度一致,因而,每个段
最大可以到4G,并且段基址也是32位的无需进行左移处理。不过此时的段寄存器存放的是段选择子。寻址时,
根据段寄存器里边的段选择子找到段描述符(里边存放段基地址),取出段基地址,最后将其与偏移地址相加
得到最终要访问地物理地址。这一套逻辑增加了操作空间,那么访问安全也是可以解决的—操作空间大,
再增加一套逻辑也无所谓。

在保护模式下,对内存的访问,仍然使用段地址和偏移地址,但是每个段在访问之前,必须先登记。
登记的信息包括段的起始地址,段的界限和段的各种访问属性等。
假设你要访问的段跟你的程序不符合,就会被阻止。也就是说操作系统底层部分,不会被恶意访问或更改。

核心部分:
GDT(全局描述符表)

GDTR(48位,全局描述符表寄存器)
请添加图片描述

0~15--全局描述符表边界  16~47--全局描述符表线性地址

32位地址部分保存的是全局描述符表在内存中的起始线性地址。
比如下边代码:
lgdt [cs: pgdt+0x7c00]    
pgdt            dw 0                ;16位,2字节,存界限
                dd 0x00007e00       ;GDT的物理地址 32位,4字节,存起始线性地址

它就表明我要在物理线性地址0x00007e00处放置全局描述符表。

为啥要加0x7c00? 
pgdt是在我当前这个程序里边。
假设我的程序在0地址处,那么就应该是 lgdt [cs:pgdt]; 但是现在我的程序在
0x7c00处,那么就应该是 lgdt [cs: pgdt+0x7c00]。

16位的边界部分保存的是全局描述符表的界限,其在数值上等于表的大小(总字节数)减一。
换句话说,全局描述符表的界限值就是表内最后一个字节(也是表内最后一个描述符的第8个字节)
的偏移量,第一个字节的偏移量是0。 
比如下边代码: 
;初始化描述符表寄存器GDTR
mov word [cs: pgdt+0x7c00],39      ;描述符表的界限
lgdt [cs: pgdt+0x7c00]

因为GDTR的界限是16位,所以该表最大是2的16次方个字节,也就是65536(64K)个字节,又因为
一个描述符占8个字节,故最多可定义8192个描述符。

段描述符表项:

这里的数据对应底层存储的数据。x86处理器在内存中按小端顺序存放和检索数据,即数据的低位字节存放在内存
的低地址中,高位字节存放在内存的高地址中。
展示数据时:
    在前面的叫高位字节,在后面的叫低位字节,就跟数学里边的数一样---最小的个位在最右边。
存储数据时:
    内存低地址: 内存地址小的。
    内存高地址: 内存地址大的。

比如:定义了一个数据
hex_data   dd 0x12345678       
这里的1234叫高位,5678叫低位
那么按x86小端顺序,其底层存储的数据为
78 56 34 12
低位在内存低地址,高位在内存高地址

由于最小存储单元为字节,所以一个字节里边的存储顺序不会改变。

请添加图片描述
请添加图片描述

这两个图片中数据对应小端顺序存储的数据。

我的段基地址为: 0x00107c00
那么按照小端顺序,7c00应该在内存低四字节里边,0010在内存高四字节里边。
段基地址31~24 : 00
段基地址23~16 : 10
段基地址15~0  : 7c00

// 低四字节  === 低位
mov dword [ebx+0x20],0x80007fff    ;基地址为0x000B8000,界限0x07FFF 
// 高四字节  === 高位
mov dword [ebx+0x24],0x0040920b    ;粒度为字节

// 连起来
0x0040920b80007fff
0b0000000001000000100100100000101110000000000000000111111111111111

0100 (G D/B L AVL)   4
G:0(字节)   D/B:1(32位)  L:0(否)  AVL:0(用户自定义位--不用管)
假设为1010
G:1(4KB)   D/B:0(16位)  L:1(64位)  AVL:0(用户自定义位--不用管)

0000  (段界限符19-16)  0

1001  (P DPL S)     9
P:1(段位于内存中)  DPL:00(0特权级系统 1 2 3用于普通程序)  S:1(代码段与数据段)
假设为0110
P:1(段位于硬盘中)  DPL:11(3特权级系统 1 2 3用于普通程序)  S:0(系统段)

0010  (子类型type X E/C W/R A)  2
X: 0(数据段)  E: 0(向上扩展--向高地址扩展)  W:1(可以正常读写)  A:0(未标记为访问)
假设为1010
X:1(代码段)  C:0(非非依从段,即该代码段只能从与它特权级相同的代码段调用,或者通过门调用)  
R:1(可读)   A:0(未标记为访问)
假设为1110
X:1(代码段)  C:0(允许从低特权级的程序转移到该段执行)  
R:1(可读)   A:0(未标记为访问)

0000  (段基地址23-16)   0

在物理内存的顺序:
FF 7F 00 80 0B 92 40 00

TYPE字段共有4位,用于指示描述符的子类型。
请添加图片描述

对于数据段,E位指示段的扩展方向。E=0表示向上扩展,即向高地址方向扩展;E=1时表示向下扩展,即向低地址
方向扩展。W位表示是否可写。若W=0表示段是不允许被写入的,否则会触发CPU异常中断,若W=1则表示段是可以
正常读写的。

对于代码段,C位表示该段是否是特权级依从。C=0表示非依从段,即该代码段只能从与它特权级相同的代码段调
用,或者通过门调用;C=1则表示允许从低特权级的程序转移到该段执行。R位表示该代码段是否可读。
A位表示该段最近是否被访问过,每当该段被访问时,CPU会自动将该位置置1。

S位用于表示描述符的类型。当S=0时,表示这是一个系统段;当S=1时,表示这是一个代码段或数据段。
1bit

DPL位表示描述符的特权级(Descriptor Privilege Level,DPL)。这两位用于指定对应段的特权
级,即0、1、2、3。其中0级为最高特权级别,3级为最低特权级别。刚进入保护模式时执行的代码具有
最高的特权级别。通常0级用于操作系统的代码,3级用于普通用户程序的代码。有些CPU指令只能由0特
权级的程序来执行。2bit

P表示段存在位(Segment Present)。P位用于指示描述符所对应的段是否存在。当P=0时,表示段位于硬盘中;当P=1时,表示段位于内存中。1bit

AVL位是用户自定义位,通常由操作系统来使用。1bit

L位是64位代码段标志,为1表示是64位。1bit

D/B位表示默认操作数大小。当为0时表示是16位的,当为1时表示是32位的。1bit

G代表段的粒度。
若G=0,则表示段界限以字节为单位,此时20位的段界限可以表示从1字节到1MB的范围;
若G=1,则表示段界限以4KB为单位,此时20位的段界限可以表示从4KB到4GB的范围。

描述符生成工具:
https://gitee.com/YMQ_1314/linux_os_learn
位置:util/gdt/gdt_generate.html
请添加图片描述

段选择子

它是描述符表项在描述符表中的段标识符。可以通过它来找到段描述符表项,从而得到段基地址。此时,只需要跟偏移地址相加,就能得出具体的物理地址。

段选择子长16位。
段选择子的高13位是描述符索引(Index).所谓描述符索引

结构如下:
请添加图片描述

|段描述符表项索引值(index)|TI|RPL|

RPL(占2位,0-1):请求特权级。

0、1、2、3。其中0级为最高特权级别,3级为最低特权级别。刚进入保护模式时执行的代码具有最高的特权级别。通常0级用于操作系统的代码,3级用于普通用户程序的代码。有些CPU指令只能由0特权级的程序来执行。
特权级就是一个辅助的东西,为了保证底层安全而提供的辅助信息。
我确定你可以访问,你才能访问,那么底层肯定就是对比。
比如:
在保护模式下,我们又是基于描述符表,这里就会有“描述符特权级”。
程序当前执行位置,肯定也会有“当前特权级”。还有其他,毕竟对比的
前提是你得有。

网络上一个待验证的说法(https://blog.csdn.net/Gyc8787/article/details/121879012):
首先,将控制直接转移到非依从的代码段,要求当前特权级CPL和请求特权级RPL都等于目标代码段描述符的DPL。即,在数值上,
    CPL=目标代码段描述符的DPL
    RPL=目标代码段描述符的DPL
  一个典型的例子就是使用jmp指令进行控制转移:
    jmp 0x0012:0x00002000
  因为两个代码段的特权级相同,故,转移后当前特权级不变。

  其次,要将控制直接转移到依从的代码段,要求当前特权级CPL和请求特权级RPL都低于,或者和目标代码段描述符的DPL相同。即,在数值上,
    CPL≥目标代码段描述符的DPL
    RPL≥目标代码段描述符的DPL
  控制转移后,当前特权级保持不变。

  第三,高特权级别的程序可以访问低特权级别的数据段,但低特权级别的程序不能访问高特权级别的数据段。访问数据段之前,肯定要对段寄存器DS、ES、FS和GS进行修改,比如
    mov fs,ax
  在这个时候,要求当前特权级CPL和请求特权级RPL都必须高于,或者和目标数据段描述符的DPL相同。即,在数值上,
    CPL≤目标数据段描述符的DPL
    RPL≤目标数据段描述符的DPL

  最后,处理器要求,在任何时候,栈段的特权级别必须和当前特权级CPL相同。因此,随着程序的执行,要对段寄存器ss的内容进行修改时,必须进行特权级检查。以下就是一个修改段寄存器ss的例子:
    mov ss,ax,
  在对段寄存器ss进行修改时,要求当前特权级CPL和请求特权级RPL必须等于目标栈段描述符的DPL。即,在数值上,
    CPL=目标栈段描述符的DPL
    RPL=目标栈段描述符的DPL

  0特权级是最高的特权级别,当一个系统的各个部分都位于0特权级时,各种特权级检查总能够获得通过,就像这种检查和检验并不存在一样。所以,处理器的设计者建议,如果不需要使用特权机制的话,可以将所有程序的特权级别都设置为0。

TI(占1位,2):引用描述符表指示位。
TI=0表示从全局描述符表GDT中读取描述符表项;
TI=1表示从局部描述符表LDT中读取描述符表项。

index(占32位,3-15):描述符索引是指描述符在描述符表中的序号(从0开始)。

我定义了如下段描述符表项:
;跳过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    ;粒度为字节

段选择子为0x0010:
jmp dword 0x0010:flush             ;16位的描述符选择子32位偏移

展开: 0b 0000 0000 0001 0000
特权级: 0b00
TI: 0b0,从GDT表中读取
段描述符索引: 0b 0000 0000 0001 0 = 2(上边的代码段)

这个0#号描述符的槽位则为 0,  一般来说下标都是从0开始的。
数据段索引:0b 0000 0000 0000 1,加上TI跟特权级,整个为0x0008

段选择子工具
位置:util/gdt/segment_selector.html
效果:
请添加图片描述

段描述符、段选择子使用例子

; nasm汇编代码
; jmp dword 0x0010:flush             ;16位的描述符选择子:32位偏移
; 这一句 ---- 就是32位寻址过程(段选择子找段描述符,取段基地址与偏移地址相加)。
mov ax,cs
    mov ss,ax
    mov sp,0x7c00     ;设置堆栈段和栈指针
    ;计算GDT所在的逻辑段地址
    mov eax,[cs:pgdt+0x7c00+0x02]      ;GDT的32位物理地址 
    xor edx,edx
    mov ebx,16
    div ebx                            ;分解成16位逻辑地址 
    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    ;粒度为字节
    ;初始化描述符表寄存器GDTR
    mov word [cs: pgdt+0x7c00],39      ;描述符表的界限   
    lgdt [cs: pgdt+0x7c00]
    in al,0x92                         ;南桥芯片内的端口 
    or al,0000_0010B
    out 0x92,al                        ;打开A20
    ; 当CPU进入保护模式之后,原有的中断向量表不再适用。因此在重新设置保护模式下的中断环境之前,
    ; 必须关中断。
    cli                                ;中断机制尚未工作
    mov eax,cr0
    or eax,1
    mov cr0,eax                        ;设置PE位
    ;以下进入保护模式... ...
    jmp dword 0x0010:flush             ;16位的描述符选择子:32位偏移
    [bits 32]                          ;清流水线并串行化处理器

flush:
    mov eax,0x0008                     ;加载数据段(0~4GB)选择子
    mov ds,eax
    
    mov eax,0x0018                     ;加载堆栈选择子
    mov ss,eax
    xor esp,esp                        ;堆栈指针 <- 0
    ...
ghalt:
    hlt
;----------------------------------------------------------------------------
    core_base_address equ 0x00040000    ;常数,内核加载的起始内存地址 
    core_start_sector equ 0x00000001    ;常数,内核的起始逻辑扇区号 
;-------------------------------------------------------------------------------
    pgdt            dw 0
                    dd 0x00007e00       ;GDT的物理地址
;-------------------------------------------------------------------------------                             
    times 510-($-$$) db 0
                     db 0x55,0xaa
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本资源为非常不错的一套王网传资源,是继之前上传的基础班的升级版,更加全面,资源过大,上传乃是下载链接,如失效请留言!!!资源远大于5积分,不多说,下面直接上目录: APC机制 I5 J$ i: U0 f1 r: O9 B( Q" b │ 01 APC的本质.mp4 │ 02 备用Apc队列.mp4: U8 p7 ]3 f" w$ b0 ?5 Z9 `0 H8 G* [ │ 03 APC挂入过程.mp48 g! H4 s1 V; ]+ b4 Y9 H0 L- B │ 04 内核APC执行过程.mp4 │ 05 用户APC执行过程.mp4 │ ├─事件等待' x% `" J' } ?& S: t' ]# I5 \5 G │ 01临界区.mp4- o( U$ W9 O+ ` ~0 u4 ~, @. \ │ 02 自旋锁.mp4) c3 ~. J& L, V& s. Q8 x/ [. w │ 03 线程等待与唤醒.mp4# b* ^" k$ d# O3 f8 t8 a3 k │ 04 WaitForSingleObject函数分析.mp4$ V7 L' C3 I( W │ 05 事件.mp4 │ 06 信号量.mp4 │ 07 互斥体.mp4 │ ├─保护模式- }! n! C$ O/ s" Q │ 014 中断门.mp4, B' i, r7 Y: B3 |! N( ^6 { l9 F │ 015 陷阱门.mp4 │ 017 任务_下.mp4, |/ M# A: K3 T7 i* Q/ ? I& o& D; p │ 018 任务门.mp46 m. D+ f4 _/ V) ~9 S& B │ 019 10-10-12分页.mp4 │ 020 PDE_PTE.mp4 │ 021 PDE_PTE属性(P_RW).mp43 ~/ ]1 x5 {4 u: {$ I │ 022 PDE_PTE属性(US_PS_A_D).mp4 │ 023 页目录基址.mp4 │ 024 页基址.mp4$ A f' [+ g6 }5 F; e │ 025 2-9-9-12分页.mp4 │ 026 2-9-9-12分页(下).mp4- ~' ~9 i0 T5 f" p2 U$ j │ 027 TLB.mp4 │ 028 中断与异常.mp4 │ 029 控制寄存器.mp46 j2 l3 j) O# {% {4 w │ 030 PWT_PCD属性.mp4 │ 031 保护模式测试.mp4 │ _001 保护模式.mp4, I; c5 X ~) t1 d1 }8 S# f3 i: b │ _002 寄存器结构.mp48 n- |- i( H$ ^* f │ _003 寄存器属性探测.mp4 │ _004 描述符选择.mp4 │ _005 描述符属性_P位_G位.mp4 │ _006 描述符属性_S位_TYPE域.mp4 │ _007 描述符属性_DB位.mp4 │ _008 权限检查.mp4 │ _009 代码跨跳转流程.mp4& S# i9 i- \0 D" @1 U- P │ _010 代码跨跳转实验.mp4" @* S2 Y- a- S6 n7 n: ~ │ _011 长调用与短调用.mp4 │ _012 调用门_上.mp4; [) _2 c8 A5 F% }! u% ]: ~. N │ _013 调用门_下.mp4 │ ├─内存管理 │ 01 线性地址的管理.mp4; ? |+ ^5 i& } │ 02 Private Memory.mp4* @3 B( Y6 ^ y- { │ 03 Mapped Memory.mp4 │ 04 物理内存的管理.mp4' [8 C6 q \1 H8 w" H2 ]0 Y │ 05 无处不在的缺页异常.mp4 │ ├─句柄 │ 01 句柄.mp4 │ 02 全局句柄.mp4 │ 5 h" u" i& {+ G4 T+ E ├─异常 │ 01 CPU异常记录.mp4 │ 02 模拟异常记录.mp4: K0 J( d1 n4 ] Q │ 03 内核异常的处理流程.mp4 │ 04 用户异常的分发.mp4 │ 05 VEH.mp4 C F6 A% j# M* @- h% N │ 06 SEH.mp4 │ 07 编译器扩展SEH课堂代码_1.mp42 I" @1 i1 b% G6 o4 O% j: t │ 08 编译器扩展SEH_2.mp4 │ 09 编译器扩展SEH_3.mp4 │ 10 编译器扩展SEH_4.mp4 │ 11 未处理异常.mp4. m' z+ `$ v- R/ K. `/ \2 M, S │ ├─消息机制0 y7 o3 ?7 X7 Z, F" I( Q │ 01 消息队列在哪.mp4$ {& n5 ]* g' H, W# k6 |+ M │ 02 窗口与线程.mp4 │ 03 消息的接收.mp4- a8 k- Q8 {! I* T8 L7 j │ 04 消息的分发.mp4- M* `$ q% z, y, R │ 05 内核回调机制.mp4 │ 0 ]( v: v$ e% _/ v, e ├─系统调用: |5 y7 Y% q' w, J │ 001 API函数的调用过程(3环部分).mp4; }0 Z8 P$ g# I6 \! _ y │ 002 API函数的调用过程(3环进0环 上).mp4- g. o" u+ M1 Y) x │ 003 API函数的调用过程(3环进0环 下).mp46 p* w2 @* j9 ?% Z3 e$ \: ? │ 004 API函数的调用过程(保存现场).mp44 G8 |/ j3 ^8 ?1 D9 Y │ 005 API函数的调用过程(系统服务).mp4 │ 006 API函数的调用过程(SSDT).mp4 │ ! A- ~, L8 M. l ├─软件调试% a8 o, z* m) E$ M( \" P D! m7 x4 B │ 01 调试对象.mp4 c- K+ k3 F( v3 p2 R9 E$ n$ f: Z6 k) @ │ 02 调试事件的采集.mp4 │ 03 调试事件的处理.mp4( w" W. m) o: D3 P7 ? │ 04 异常的处理流程.mp4 │ 05 软件断点.mp4 │ 06 内存断点.mp4 │ 07 硬件断点.mp4 │ 08 单步异常.mp4% P5 e* U+ M# a1 j3 D6 n; n │ 09 单步步过.mp4 │ 10 硬件HOOK过检测.mp46 H5 q2 K& X1 u$ ]/ E │ ├─进程与线程 │ 001 进程结构体.mp4 │ 002 线程结构体.mp41 `5 e+ [1 U) j │ 003 KPCR.mp4 │ 004 等待链_调度链.mp41 m! T& `3 t' U& U# A- @+ _ │ 005 模拟线程切换.mp4& ?, D% H/ z- d# _& \$ X- X$ U │ 006 Windows线程切换_主动切换.mp4 │ 007 Windows线程切换_时钟中断切换.mp4/ s& N% Y5 B" @2 g │ 008 Windows线程切换_时间片管理.mp48 X( v. g" T0 ~- k! v* Q │ 009 Windows线程切换_TSS.mp4 n+ A9 L5 B2 t* M# H │ 010 Windows线程切换_FS.mp4 │ 011 Windows线程切换_线程优先级.mp4 A! a% n1 c. Y5 y# ~ L4 P │ 012 进程挂靠.mp4 │ 013 跨进程读写内存.mp4, E0 ^0 U I1 h │ $ {. ?; O) C* w1 K. q) K └─驱动开发 01 驱动开发环境配置.mp4* W) g2 z& T/ _; @1 V" n 02 第一个驱动程序.mp4 03 如何调试驱动程序.mp4; [8 U2 T) B' V 04 内核编程基础.mp4 05 内核空间与内核模块.mp4 06 0环与3环通信(常规方式).mp46 O: Z; `3 `( L 07 SSTD HOOK.mp46 D t( {, u1 D/ x) h! ]: g 08 Inline Hook.mp4 09 多核同步之临界区.mp40 l& ^, e3 J( E1 d( b2 S 10 多核同步之自旋锁.mp4 11 重载内核

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值