冯.诺依曼架构优点:总线开销小,控制逻辑实现简单。
程序的存储与执行
- hello.c文件 经过编译、链接 形成a.out文件,存储在硬盘上。
- 然后将硬盘上的a.out文件加载到内存上去。
- 取指把内存上的指令取到寄存器中去。译码就是将01二进制翻译成机器能识别的动作。
一个mini的计算机实现c = a+b
- 首先将a,b从内存加载到寄存器中。因为ALU只能访问寄存器。
- ALU将a+b计算出来得到c,再将c替换到寄存器中。
- 最后将寄存器中的c加载到硬盘上。
其中的机器指令设计,有不同的编码方式
a.out放在内存中就相当于下图的右侧。
因为采用冯.诺依曼体系架构,所以数据和指令都放在同一内存区域。其中黄色部分就代表指令,绿色就代表数据。
编程语言的进化
存储设备的层次结构
ISA的基本介绍
ISA:Instruction Set Architecture指令集架构。是底层硬件电路面向上层软件程序提供的一层接口规范
ISA定义了:
- BYTE/HALFWORD/WORD
- 寄存器
- 指令
- 寻址模式
- 异常或者中断的处理方式
- …
ISA为操作系统提供一层抽象,制定了规则和约束,让编程者不用操心具体的电路结构。
- CISC复杂指令集:针对特定的功能实现特定的指令,导致指令数目比较多,但生成的程序长度较短。
- RISC精简指令集:只定义常用指令,对复杂的功能采用常用指令组合实现。
ISA的宽度指的是CPU中通用寄存器的宽度(二进制的位数),这决定了寻址范围的大小、以及数据运算的能力。
ISA的宽度和指令编码长度无关。
RISC-V基本介绍
- X86(复杂指令集架构):复杂,IP问题。
- ARM:复杂,在2010年还不支持64位,IP问题。
ISA命名格式:RV[###][abc…xyz]
- RV:用于标识RISC-V体系架构的前缀,即RISC-V的缩写。
- {###}:{32,64,128}用于标识处理器的字宽,也就是处理器的寄存器的宽度(bit)。
- [abc…xyz]:标识该处理器支持的指令集模块集合。
模块化的ISA
RISC ISA = 1个基本整数指令集 + 多个可选的扩展指令集
- 基本整数指令集(Integer):唯一强制要求实现的基础指令集。
- 扩展模块指令集:特定组合“IMAFD”被称为“通用”,通常用G标识。
RISC-V的Unprivileged Specification定义了32个通用寄存器以及一个PC。 - 对RV32I、RV64I、RV128I都一样
- 如果实现支持F/D扩展则需要则外支持32位浮点寄存器。
- 寄存器的宽度由ISA指定,RV32的寄存器宽度为32位,RV64的寄存器宽度为64位,依次类推。
每个寄存器具体编程时有特定的用途以及各自的别名。由RISC-V Application Binary Interface(ABI)定义。
HART
HART = HARdware Thread 硬件线程
特权级别(Privileged Level) - RISC-V定义了三个特权级别。
- Machine级别是最高的级别,所有的实现都需要支持。Machine态只能访问物理地址。
- 不同的特权级别下分别对应各自的一套Register(CSR),用于控制和获取相应Level下的处理器工作状态。
- 高级别的特权级别下可以访问低级别的CSR,譬如Machine Level下可以访问Supervisor/User Level的CSR。
- RISC-V定义了专门用于操作CSR的指令(Zicsr)
- 特定的指令可以用于在不同的级别之间切换(ECALL/EBREAK)
内存管理与保护
- 物理内存保护(Physical Memory Protection,PMP):允许M模式指定U模式可以访问的内存地址;支持R/W/X,以及LOCK。
- 虚拟内存:需要支持Supervisor LEVEL;用于实现高级的操作系统特性。虚拟地址和物理地址的转换由特殊的硬件MMU实现。
异常和中断
编译与链接
GCC(GNU Compiler Collection)
- 由GNU开发。
- 支持C、C++和Go等多种语言,可被移植到各种计算机体系架构上,如x86、ARM、RISC-V等。
GCC的命令格式
- 预处理:把标准的宏语言转成C语言
GCC的主要执行步骤
- 编译:编译器完成“预处理”和“编译”。预处理:处理源文件中以#开头的预处理指令,例如#include、#define等。编译:针对预处理的结果进行一系列的词法分析、语法分析、语义分析,优化后生成汇编指令,存放在.o的目标文件中。
- 汇编:汇编器将汇编代码转换为机器可以执行的代码。
- 链接:链接器将汇编器生成的目标文件和一些标准库(例如lib)文件组合,形成最后的可执行的应用程序。
GCC设计的文件类型
针对多个源文件的处理
ELF
ELF(executable linkable format)是一种Unix-like系统上的二进制文件格式。
ELF格式的文件分类:
ELF文件格式
ELF文件处理相关工具:
生成目标文件
gcc -c hello.c
查看ELF文件头信息
readelf -h hello.o
查看hello.o的Section header table
readelf -SW hello.o
查看hello.o的反汇编
gcc -g -c hello.c
objdump -S hello.o
嵌入式开发
参与编译和运行的机器根据其角色可分为三类:
- 构建系统:生成编译器可执行程序的计算机系统。
- 主机系统:运行编译器可执行程序的计算机系统,编译链接应用的计算机系统。
- 目标系统:运行应用程序的计算机系统。
编译方式分类:
- 本地编译 build = host = target
- 交叉编译 build = host != target
平时我们所使用的gcc编译器编译出来的a.out文件只能在x86上运行,所以我们需要自己做出来一个编译器。
调试器GDB
GDB基本调试流程
模拟器QEMU