BY eHWRITTEN ON HALO3 MIN READ

第零章的爆炸信息量

第零章的爆炸信息量 实模式 保护模式 权限级别(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)】