笔记:深入理解计算机系统(四)

ShadowC

| 本文阅读量: -

计算机基础补完计划 - 自学计算机科学相关课程。此部分为深入理解计算机系统及相关视频课程的学习笔记。此部分主要讲指令集和体系架构。

1. Overview

以C语言在x86架构的机器上编码为例,程序的执行速度主要受到代码算法、编译器从源代码向汇编代码的转换、指令集架构(ISA,Instruction Set Architecture,处理器提供给编译器的指令集合)、硬件本身四个层次的影响。

指令集架构定义了三方面的重要内容:

  1. 系统状态(例如寄存器、内存、编程计数器等;
    • CPU包含多少寄存器,长度是多少字节;
    • 如何指明内存地址(段地址:偏移地址);
  2. CPU可以执行的指令;
    • 包含哪些指令,对应哪些功能,如何被编码(如 add -> 10101;
    • 复杂指令集CISC(Complex instruction set computer)。精简指令集RISC
  3. 每条指令对系统状态的影响。

几个标志性的架构:

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)包括三种数据:

  1. PC,Program counter,程序计数器,指向下一条指令的地址,被称为EIP(IA32)或RIP(x86-64);
  2. 寄存器文件(Register file),存放高频使用的程序数据;
  3. 条件代码(Conditional codes),存放最近的数学操作的状态信息,用于条件分支的选择。

内存则是以字节为单位寻址的数组(Byte addressable array),存放代码、数据和部分系统数据,包括支撑程序的栈。

从C代码到对象代码(Object code)再到机器码

如gcc等C语言编译过程,会将C代码转换为汇编代码,然后转换为Object Code(目标机器的机器码),链接必要的库后生成可执行文件。

汇编代码中主要有三种类型的指令:

  1. 在寄存器或者内存数据上及逆行数学操作;
  2. 在内存和寄存器之间传输数据(读、写);
  3. 跳转控制(Transfer control),包括非条件跳转和条件跳转。

而汇编代码中的数据类型也只有两种:

  1. 整数,可以被视为数据值,也可以被视为地址。
  2. 浮点数 ;

在汇编代码层级,没有集合类型,只有在内存中连续分配的字节。

为了便于查看,可以将机器码反汇编为汇编代码,如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的额外八个寄存器。