第零章的爆炸信息量
第零章的爆炸信息量 实模式 保护模式 权限级别(ring0) mov al,[cs:ip] mov cx,5 ;cx(count register) mov si,0x1000 ;SI source index mov di,0x2000 ;DI destination index cls

第零章的爆炸信息量
-
实模式
-
保护模式
-
权限级别(ring0)
mov al,[cs:ip] mov cx,5 ;cx(count register) mov si,0x1000 ;SI source index mov di,0x2000 ;DI destination index cls ;清除方向标志,DF=0,让字符串正向拷贝 rep movsb ;把DS:SI->ES:DI 拷贝c个字节 movsb不需要手动指定地址source Destination DS:SI ES:DI -
内存分段:数据段和代码段(section/segment)段寄存器-》内存
-
平坦模型
-
处理器的分页
-
程序计数器cs:eip
-
当前指令长度+地址=下一条指令地址
-
使用jmp跳过数据区
jmp start var dd 1 start: mov ax,0 ;在cpu视角,只要指令在逻辑上是连续即可,cpu本身无法区分数据段和代码代码段,只需要执行cs:ip命令 -
分数据段和代码段的原因
-
不同读写权限
GDT(global descriptor table) 这个表中每一项被称为段描述符,操作系统让cpu进入保护模式之前,,首先 准备好GDT
-
S 1bit
-
TYPE 4bit
关于GDT,取决于操作系统,编译器指定了READ only区域和rw区域,但是需要注意的是,编译器并没有让段具有一定的属性,只是划分,对于代码段,只是将多个section合并segment
操作系统通过设置GDT,在段描述符指定段的位置,大小,属性(包含S和TYPE字段)
-
-
提高缓存命中
-
节省内存
-
-
后面会谈论GDT的维护,cpu对代码的执行如何体现CPU来在运行时决策对数据的保护(编译器,OS,CPU三者配合)
section my_code vstart=0
;通过跳转的方式给cs赋值0x90
jmp 0x90:start
start:
;初始化数据段寄存器DS(DataSegment)
mov ax,section.my_data.start
add ax,0x900 ;本程序被MBR加载到内存0x900
shr ax,4 ;段基
mov ds,ax
;SS(Stack Segment)
mov ax,section.my_stack.start
add ax,900
shr ax,4
mov ss,ax
mov
-
用户函数不具备日独立打印字符能力
extern int printf (__const char *__restrict __format,...); //注意这不是认为添加进去的省略号,而是一个变长参数语法 //有了这句生命,就无需include<stdio.h -
runtimelib 运行时库 && glibc
CRT(C Run-Time library)
- ltrace
- strace
-
MBR(Master Boot Record)
存在硬盘最开始的区域(nvme0n0p1)
这个扇区被称为引导扇区
MBR扇区的内容
- 446byte引导程序和参数
- 64byte的分区表
- 2byte的结束标记(magic number) 55aa
约定好将MBR引导程序加载到物理地址0x7c00
mbr的分区表理论上只能存储四项记录,每项目对应一个主分区或者扩展分区
-
扩展分区
为了突破分区数量的限制,在扩展分区的虚拟0扇区可以划分出EBR引导扇区,可以有多个逻辑分区,【
然后继续接力给OBR(OS-Boot Record)】