计算机基础补完计划 - 自学计算机科学相关课程。此部分为深入理解计算机系统及相关视频课程的学习笔记。此部分主要讲指令集和体系架构。
1. Overview
以C语言在x86架构的机器上编码为例,程序的执行速度主要受到代码算法、编译器从源代码向汇编代码的转换、指令集架构(ISA,Instruction Set Architecture,处理器提供给编译器的指令集合)、硬件本身四个层次的影响。
指令集架构定义了三方面的重要内容:
- 系统状态(例如寄存器、内存、编程计数器等;
- CPU包含多少寄存器,长度是多少字节;
- 如何指明内存地址(段地址:偏移地址);
- CPU可以执行的指令;
- 包含哪些指令,对应哪些功能,如何被编码(如 add -> 10101;
- 复杂指令集CISC(Complex instruction set computer)。精简指令集RISC
- 每条指令对系统状态的影响。
几个标志性的架构:
8086 | 1978年面世 | 29K晶体管 | 5-10Mhz主频 | 第一款16位处理器 |
---|---|---|---|---|
1MB寻址空间 | ||||
386 | 1985 | 275K | 16-33Mhz | 第一款32位处理器,涉及IA32(32位架构) |
可运行Unix | 加入了“Flat address“特性 | 32位Linux/Gcc的默认安装为i386 | ||
Pentium 4F | 2005 | 230M | 2800-3800Mhz | 第一款64位X86_64架构处理器 |
2. Definitons
Architecture(also instruction set architecture, ISA), is the part of a processor design that one needs to understand to write assembly code.
**架构(指令集架构)**是为编写汇编代码而所需了解的处理器设计结构。(软硬件之间的接口定义)。
“What is directly visible to software.”
Microarchitecture: Implementation of the architecture.
微体系结构指的是架构的实现。
这里的指令集架构和微体系结构的管理类似于Linux内核设计中体现的策略与机制分离的思想,指令集架构定义接口(对软件可见),而微体系结构负责实现结构(对软件不可见)。
程序可见的状态(Programmer-Visible State)包括三种数据:
- PC,Program counter,程序计数器,指向下一条指令的地址,被称为EIP(IA32)或RIP(x86-64);
- 寄存器文件(Register file),存放高频使用的程序数据;
- 条件代码(Conditional codes),存放最近的数学操作的状态信息,用于条件分支的选择。
内存则是以字节为单位寻址的数组(Byte addressable array),存放代码、数据和部分系统数据,包括支撑程序的栈。
从C代码到对象代码(Object code)再到机器码
如gcc等C语言编译过程,会将C代码转换为汇编代码,然后转换为Object Code(目标机器的机器码),链接必要的库后生成可执行文件。
汇编代码中主要有三种类型的指令:
- 在寄存器或者内存数据上及逆行数学操作;
- 在内存和寄存器之间传输数据(读、写);
- 跳转控制(Transfer control),包括非条件跳转和条件跳转。
而汇编代码中的数据类型也只有两种:
- 整数,可以被视为数据值,也可以被视为地址。
- 浮点数 ;
在汇编代码层级,没有集合类型,只有在内存中连续分配的字节。
为了便于查看,可以将机器码反汇编为汇编代码,如Linux下的objdump工具:
objdump -d [target]
寄存器是CPU中存储少量数据的位置,CPU可以迅速从这里获得数据(一个时钟周期);同时寄存器也是汇编语言的核心,它们是所有架构的宝贵核心,尤其是x86。
IA32中有8个寄存器:
寄存器 | 用途 | 备注 |
---|---|---|
EAX | 累加器(Accumulate) | 一般目的用(General purpose) |
EBX | 基址寄存器(Base) | |
ECX | 计数(Count) | | |
EDX | 存放数据(Data) | | |
EBP | 堆栈指针(Stack Pointer) | | |
EBP | 堆栈指针(Stack Pointer) | 一般目的用 |
ESI | 源变址(Source Index) | |
EDI | 目标变址(Destinatin Index) |
x86-64架构下的寄存器与上表类似,但是为%rax、%rbx等等,可用eax
指向其中的后32位,同样可以用ax,ah等分别访问其中2字节和1字节的部分。同时x86-64架构下提供了r8-r15的额外八个寄存器。