0%

CSAPP 学习笔记 3 程序的机器级表示

这两周看了第三章的前面五节,对机器指令有了更进一步的认识。

程序的机器级表示 阅读进度

历史观点

Intel处理器系列俗称x86,它有着一段进化之旅。从最初的8086到i386,再到i5和i7。那么它究竟有哪些方面的提升呢?

  • 晶体管数量增加。Core i7的1.4G个晶体管,是8086芯片29K个晶体管的4.8万倍。晶体管越多,意味着芯片的电路越复杂,能力越强。
  • 指令集变大,支持更多指令。8087在8086的基础上,建立了浮点模型。
  • 更多的位数。Pentium 4E是Intel对AMD提出的对IA32的64位拓展的实现,我们称之为x86-64。
  • 更多的核数。Core 2是Intel的第一个多核微处理器。
  • 更多的技术。Pentium 4E增加了超线程,允许一个处理器上同时运行两个程序。

AMD等产商的大多处理器与Intel处理器兼容,能够运行完全相同的机器级程序。

程序编码

什么是机器代码呢?我们知道,C语言会经过预处理、编译、汇编、链接这些过程。

  • 预编译:拓展源代码,主要处理对象是#include及#define。
  • 编译:产生源文件的汇编代码,拓展名为.s。
  • 汇编:产生二进制目标代码,拓展名为.o。
  • 链接:将多个.o文件转化成一个可执行文件。

所谓机器代码,第一种是指.o文件中的代码,第二种是指可执行文件中的代码。它们的区别在于前者还没有填入全局值的地址。

机器代码是一些二进制代码,不具有可读性。汇编代码非常接近机器代码,我们可通过学习汇编代码来认识机器代码。

数据格式

Intel的体系结构一直在变化,从16位到32位,再到64位,可能以后还会拓展到128位。

Intel用以下术语来表示不同的数据类型。

Intel数据类型 汇编代码后缀 大小(字节)
字节 b 1
w 2
双字 l 4
四字 q 8
单精度 s 4
双精度 l 8

访问信息

一个CPU包含一组16个存储64位值的通用目的寄存器,这些寄存器用来存储整数数据和指针。

我们知道,程序运行时,其数据存放在内存中。CPU需要一些指令来进行内存与寄存器间的数据转移,称为数据转移指令。

我们也知道,程序运行时,在内存中有一个对应的程序栈。CPU有专门指令进行入栈、出栈操作。可否将这些指令去掉呢?可以,存在代替指令。但是这样做,会让机器代码增多,考虑到入栈出栈操作是非常常见的,所以提供专门的指令会缩减机器代码的大小。这也就是在精简指令集上编译出来的机器代码比复杂指令集庞大的原因。

算术和逻辑操作

所谓算术操作,指的是加减乘除等操作。所谓逻辑操作,是指与或移位等操作。

通过学习汇编代码的算术和逻辑操作,对于高级语言的便利性有了更具体的认识。一条C语言简单的算术表达式,转化成汇编代码,会变成多条。对于一些更复杂的循环控制语句,就更复杂了。

(全文完)