深入理解计算机系统 第三章 程序的机器级表示(1)

计算机执行机器代码,用字节序列编码低级的操作,包括处理数据、管理内存、读写存储设备上的数据,以及利用网络通信。编译器基于编程语言的规则、目标机器的指令集和操作系统遵循的惯例,经过一系列的阶段生成机器代码。GCC C语言编译器以汇编代码的形式产生输出,汇编代码是机器代码的文本表示,给出程序中的每一条指令。然后GCC调用汇编器和链接器,根据汇编代码生成可执行的机器代码。

机器级编程中两种抽象:

  第一种是由指令集体系结构或指令集架构(ISA)来定义机器级程序的格式和行为,它定义了处理器状态、指令的格式,以及每条指令对状态的影响。大多数ISA。

  第二种抽象是,机器级程序使用的内存地址是虚拟地址,提供的内存模型看上去是一个非常大的字节数组。

数据格式:

  标准int值存储为双字(32位)。指针(在此用char*表示)存储为8字节的四字。
  浮点数主要有两种形式:单精度(4字节)值,对应于C语言数据类型float;双精度(8字节)值,对应于C语言数据类型double。
GCC生成的汇编代码指令字符的后缀,表明操作数的大小。例如,数据传送指令有四个变种:movb(传送字节)、movw(传送字)、movl(传送双字)、movq(传送四字)。后缀‘l’用来表示双字,因为32位数被看成是“长字(long word)”。
操作数(operand),指示出执行一个操作中要使用的源数据值,以及放置结果的目的位置。
操作数的三种类型:
  第一种类型是立即数(immediate),用来表示常数值。
  第二种类型是寄存器(register),它表示某个寄存器的内容,16个寄存器的低位1字节、2字节、4字节或8字节中的一个作为操作数,这些字节数分别对应于8位、16位、32位或64位。
  第三类操作数是内存引用,它会根据计算出来的地址(通常称为有效地址)访问某个内存位置。
算术和逻辑操作:
  指令类ADD由四条加法指令组成:addb、addw、addl和addq,分别是字节加法、字加法、双字加法和四字加法。
  给出的每个指令类都有对这四种不同大小数据的指令。这些操作被分为四组:加载有效地址、一元操作、二元操作和移位。
  二元操作有两个操作数,而一元操作有一个操作数。
控制:
  测试数据值,然后根据测试的结果来改变控制流或者数据流。
  用jump指令可以改变一组机器代码指令的执行顺序,jump指令指定控制应该被传递到程序的某个其他部分,可能是依赖于某个测试的结果。
条件码(condition code)寄存器,它们描述了最近的算术或逻辑操作的属性。可以检测这些寄存器来执行条件分支指令。
最常用的条件码有:
  CF:进位标志。最近的操作使最高位产生了进位。可用来检查无符号操作的溢出。
  ZF:零标志。最近的操作得出的结果为0。
  SF:符号标志。最近的操作得到的结果为负数。
  OF:溢出标志。最近的操作导致一个补码溢出----正溢出或负溢出。