CSAPP学习笔记(四)

Posted by HK on January 28, 2019

第三章 详细学习一种特别的汇编语言,了解如何将C程序编译成这种形式的机器代码。

逆向工程(reverse engineering):通过研究系统和逆向工作,来视图了解系统的创建过程。

Intel处理器系列俗称x86。K 10^3,M 10^6,G 10^9。

程序编码

假设一个C程序,有两个文件p1.c和p2.c:

gcc -Og -o p p1.c p2.c

编译选项-Og告诉编译器使用会生成复合原始C代码整体结构的及其代码的优化等级。一般选择优化级别-O1,-O2。

将源代码转化成可执行代码。 -C预处理器扩展源代码,插入所有用#include命令制定的文件,并扩展所有用#define声明指定的宏。 -编译器产生两个源文件的汇编代码,名字分别为p1.s和p2.s。 -汇编器会将汇编代码转化成二进制目标代码文件p1.o和p2.o。 -链接器将两个目标代码文件与实现库函数(如printf)的代码合并,并产生最终的可执行代码文件p(由命令行指示符-o p指定的)。

目标代码是机器代码的一种形式,它包含所有指令的二进制表示,但还没有填入全局值的地址。可执行代码是机器代码的第二种形式。

机器级代码

计算机系统的两种抽象:

  1. 指令集体系结构或指令集架构ISA:定义机器级程序的格式和行为,它定义了处理器状态、指令的格式,以及每条指令对状态的影响。
  2. 机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个非常大的字节数组。存储器系统的实际实现是将多个硬件存储器和操作系统软件组合起来。

-程序计数器(pc,在x86-64中用%rip表示):给出将要执行的下一条指令在内存中的地址。 -整数寄存器:整数寄存器文件包含16个命名的位置,分别存储64位的值。存储地址(对应于C语言的指针)或整数数据,有的寄存器被用来记录某些重要的程序状态,而其他的寄存器用来保存临时数据。例如过程的参数和局部变量,以及函数的返回值。 -条件码寄存器:保存最近执行的算术或逻辑指令的状态信息。用来实现控制或数据流中的条件变化。 -向量寄存器:存放一个或多个整数或浮点数值。