AnKate
898 words
4 minutes
CSAPP 3.2&3.3
2020-10-12

程序编码#

以书上所举的编译p1、p2两个c语言文件的过程为例,可以将gcc编译的过程大致分为如下几步:

  1. C preprocessor(预处理器)进行预编译,简单理解为将带有”#“符号的语句进行编译,包括但不限于对头文件、宏定义、全局变量的编译。
  2. compiler(编译器)进行汇编,生成.s文件。
  3. assembler(汇编器)将汇编代码转化成机器可执行的二进制代码(目标代码),生成.o文件。
  4. linker(链接器)将所用函数链接到动态或静态库,产生最终的可执行文件。

书中所用到的两种抽象#

计算机系统中为了便于理解,采用了两种较为重要的抽象:

第一种采用了ISA(instruction set architecture)将处理器的运作进行抽象,简化为每条指令按顺序进行,一条结束后再进行下一条。实际的处理器运行更为复杂,能够同时处理多条指令。

第二种将内存地址抽象为虚拟地址,表现为某种字节数组。实际的内存地址是硬件存储器和系统软件组合实现的。

可见的处理器状态#

  • PC(Program Counter,程序计数器,在x86-64中用%rip表示),会给出下一条待执行指令在内存中的位置。
  • 整数寄存器(integer register file)包含了16个命名的位置,它们都能够存储64位的值。寄存器能够存储地址或整数数据。一些寄存器用来保存程序的重要章台,一些用来保存临时数据,例如参数和局部变量,以及函数返回值。
  • 条件码寄存器(condition code register)保存最近进行的逻辑或算术运算的结果,用于控制条件变化,如if和while语句。
  • 向量寄存器(vector register)用于存放一个或多个整型或浮点型数据。

程序内存中包含的内容#

  • 可执行的机器代码
  • 操作系统需要的一些信息
  • 用于管理运行过程中的函数调用与返回的栈
  • 用户申请分配的内存

机器级代码#

机器级代码通常难以阅读和理解,为了查看机器级代码的内容,需要用到反汇编器(disassembler),将机器级代码转化为类似汇编代码的形式。

有关于机器级代码和反汇编器有如下特征:

  • x86-64的指令长度有1至15字节不等,常用的、或是运算对象少的一些指令所需的字节更少。
  • 字节能够与汇编指令一一对应。
  • 反汇编程序只根据字节进行反汇编,不需要访问源代码或汇编代码。
  • 汇编代码中的后缀代表数据类型,反汇编代码中的后缀添加在call或ret指令后,均可忽略。

数据格式#

在计算机系统中,使用”word”表示16位数据类型,“double words”表示32位数据类型,“quad words”表示64位数据类型。

在x86-64的指令集中,包括了对各种数据类型以及指针的操作指令。

下表中列举了汇编代码中的后缀对应的数据类型,以及它们的数据大小。

C语言对应的数据类型Intel系统下的数据类型汇编代码中对应后缀数据大小(单位:Byte)
charByteb1
shortWordw2
intDouble Wordl4
longQuad Wordq8
char *Quad Wordq8
floatSingle precisions4
doubleDouble precisionl8

在64位的操作系统中,指针是8Byte的。

CSAPP 3.2&3.3
https://ankate.github.io/posts/csapp-3233/
Author
AnKate
Published at
2020-10-12