04 June 2013

汇编代码是机器代码的文本表示。

机器级代码

计算机系统使用了不同形式的抽象,利用更简单的抽象来隐藏实现的细节。对于机器级编程来说,其中两种抽象尤为重要。

一个是机器级程序的格式和行为,定义为指令体系结构(Instruction Set Architecture,ISA ),它定义了处理器状态,指令的格式以及每条指令对状态的影响。大多数ISA,包括IA32和x86-64,将程序的行为描述成好像每条指令时顺序执行的。一条指令执行结束后,下一条指令开始执行。处理器的硬件远远比描述的精细复杂,它们能够并发的地执行许多指令,但是可以采取措施保证整体行为与ISA指定的顺序执行行为一致。

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

在整个编译过程中,编译器会主要将C语言提供的相对抽象的执行模型表示的程序转化为处理器执行的非常基本的命令。汇编代码非常接近于机器代码。与机器码的二进制格式相比,汇编代码的一个主要特点是,它用可读性更好的文本格式来表示。

能够理解汇编代码以及它与原始C代码的联系,是理解计算机系统如何执行程序关键的一步。

IA32机器代码和原始的C代码差异非常大,一些通常对C语言程序员隐藏的处理器状态在机器代码中是可见的:

  • 程序计数器(在IA32中,通常称之为PC,用%eip表示)指示将要执行的下一条指令在存储器中的地址
  • 整数寄存器文件包含8个命名的位置,分别存储32位的值。这些寄存器可以存储地址或者整形数据。有的寄存器是用来记录某些重要的程序状态,而其他的寄存器是用来保存临时数据,比如过程的局部变量和函数的返回值。
  • 条件码寄存器保存着最近执行的算术和逻辑指令的状态信息,它们用来实现控制或数据流的条件变化,比如用来实现if和while语句。
  • 一组浮点寄存器用来存放浮点数据。

虽然C语言提供了一种模型,可以用来在存储器中声明和分配各种数据类型的对象,但是机器代码仅仅将存储器看成一个很大的,按字节寻址的数组。C语言中提供的聚合数据类型,比如数组和结构,在机器代码中用连续的一组字节来表示。即使是标量数据类型,汇编代码也不区分有符号或无符号整数,不区分各种类型的指针,甚至不区分指针和整数。

附录

  1. 学习汇编,需要看下王爽老师的<<汇编语言>>,CSAPP里面的介绍不是很好. 更新于2013.11.24


blog comments powered by Disqus