系统概念

 

维基百科-加法器 半加器的分解

存储

大小端

数据在CPU内存中有两种存放方式, 假设数据0x12345678从地址0x1000开始存放

大端

大端是高字节存放到内存低地址

$0x12345678$ 中 $0x12$存到低地址, $0x78$存到高地址

graph LR;
    subgraph B[大端]
        B1(0x12)
        B2(0x34)
        B3(0x56)
        B4(0x78)
    end
    subgraph A[地址]
        A1(0x1000)
        A2(0x1008)
        A3(0x1010)
        A4(0x1018)
    end
    B1-->A1
    B2-->A2
    B3-->A3
    B4-->A4

小端

小端是高字节存放到内存高地址

$0x12345678$ 中 $0x12$存到高地址, $0x78$存到低地址

graph LR;
    subgraph S[小端]
        S1(0x78)
        S2(0x56)
        S3(0x34)
        S4(0x12)
    end
    subgraph A[地址]
        A1(0x1000)
        A2(0x1008)
        A3(0x1010)
        A4(0x1018)
    end
    S1-->A1
    S2-->A2
    S3-->A3
    S4-->A4

有效字节

  • MSB(most significant byte), 最高有效字节

  • LSB(least significant byte), 最低有效字节

32位int型数$0x12345678$, MSB为$0x12$, LSB为$0x78$

大小

bit 意为位或比特, 是电子计算机中最小数据单位

每一位状态只能是 01

字节

Byte意为字节, 是计算机处理数据基本单位

1字节为8位, 1Byte = 8bit

graph LR;
    subgraph S[Byte]
        A0(bit)
        A1(bit)
        A2(bit)
        A3(bit)
        A4(bit)
        A5(bit)
        A6(bit)
        A7(bit)
    end

格式

  • ASCII码

一个英文字母占一个字节空间, 如一个ASCII码就是一个字节

  • UTF-8编码

一个英文字符等于一个字节, 一个中文(含繁体)等于三个字节

中文标点占三个字节, 英文标点占一个字节

  • Unicode编码

一个英文等于两个字节, 一个中文(含繁体)等于两个字节, 中文标点占两个字节, 英文标点占两个字节

编码

原码

正数

按照绝对值大小转换成二进制数

  • 示例, $32$位系统中, $5$原码为

$00000000$ $00000000$ $00000000$ $00000101$

负数

按照绝对值大小转换成二进制数, 且最高位补$1$

  • 示例, $32$位系统中, $-5$原码为

$10000000$ $00000000$ $00000000$ $00000101$

反码

正数

反码与原码相同

负数

对原码中除符号位之外每位取反

  • 示例, $32$位系统中, $-5$反码为

$1111111$ $11111111$ $11111111$ $11111010$

补码

正数

补码与原码相同

负数

补码为反码最后一位加1

  • 示例, $32$位系统中, $-5$补码为

$1111111$ $11111111$ $11111111$ $11111011$

加法

整数

[$A$]$_补$ $+$ [$B$]$_补$ $=$ [$A+B$]$_补$ $mod$ $2^{n+1}$

小数

[$A$]$_补$ $+$ [$B$]$_补$ $=$ [$A+B$]$_补$ $mod$ $2$

减法

整数

[$A-B$]$_补$ $=$ [$A$]$_补$ $+$ [$-B$]$_补$ $mod$ $2^{n+1}$

小数

[$A-B$]$_补$ $=$ [$A$]$_补$ $+$ [$-B$]$_补$ $mod$ $2$

计算

半加器

将两个一位二进制数相加

  • 输入端口 $A$, $B$

  • 输出端口 进位 $C$ = $A$ & $B$, 和 $S$ = $A$ ^ $B$

输入A 输入B 进位 C 和 S
0 0 0 0
1 0 0 1
0 1 0 1
1 1 1 0

全加器

全加器(full adder)将两个一位二进制数相加, 并根据接收到的低位进位信号, 输出和、进位输出

全加器三个输入信号为两个加数A、B和低位进位Cin

全加器通常可以通过级联(cascade)方式, 构成多位(如8位、16位、32位)二进制数加法器的基本部分

$A$ $B$ $Cin$ $Cout$ $S$
0 0 0 0 0
1 0 0 0 1
0 1 0 0 1
1 1 0 1 0
0 0 1 0 1
1 0 1 1 0
0 1 1 1 0
1 1 1 1 1

脉动进位加法器

// 全加器代码
int add(int a, int b) {
    int c;
    int s;
    if (a == 0 || b == 0) {
        return 0;
    }
    // 进位标志
    c = a & b;

    // 进位c左移1位
    c <<= 1;
    // 当前和s
    s = a ^ b;
    // 结束标志是输入值一个为0
    return add(s, c);
}

3 + 9 = 12 $->$ 0011 + 1001 = 1100

寄存器

通用寄存器

名称 作用
ax 累积暂存器
bx 基底暂存器
cx 计数暂存器
dx 资料暂存器
名称 作用
eax 累加器(accumulator), 是很多加法乘法指令的缺省寄存器
ebx 基地址(base)寄存器, 在内存寻址时存放基地址
ecx 计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器
edx 用来放整数除法产生的余数

索引暂存器

名称 作用
si 来源索引暂存器
di 目的索引暂存器
名称 作用
esi 源索引寄存器(source index)
edi 目标索引寄存器(destination index)

用于字符串操作指令, esi指向源串, edi指向目标串

堆叠、基底暂存器

名称 作用
sp 堆叠指标暂存器
bp 基底指标暂存器
名称 作用
esp 堆栈指针
ebp 基址指针(base pointer), 用作高级语言函数调用的”框架指针”

esp 专门用作堆栈指针, 被形象地称为栈顶指针, 堆栈顶部是地址小区域, 压入堆栈数据时, 在32位平台上esp每次减少4字节

从零开始写OS内核-BIOS启动到实模式

启动

读取 BIOS

按下电源按钮后, 计算机首先读取一块存储有基本输入输出系統即 BIOS 程序的芯片

开机后 CPU 初始模式是实模式, 地址宽度为 20 位, 即最大地址空间 1MB, 其划分固定, 每一块都被映射到不同设备上

BIOS作用

(1) 开机后 CPU 指令寄存器 IP 被强置为地址 0xFFFF0, 该地址被映射到 BIOS 固件上代码, 是计算机开机后第一条指令地址

(2) CPU 开始执行 BIOS 上代码, 这一部分主要是硬件输入输出设备相关的检查, 以及建立一个最初中断向量表

(3) BIOS 代码最后阶段工作, 是检查启动盘上 MBR 分区, 即磁盘上第一个 512B 内容, 又叫引导分区

BIOS 会对这 512B 做一个检查, 其最后2个字节必须是0x55 和 0xaa, 否则就不是合法启动盘

(4) 检查通过后, BIOS 将这 512B 加载到内存 0x7C00 处, 到 0x7E00 为止, 然后指令跳转到 0x7C00 开始执行

内存布局规划

TODO