文章也同时在个人博客 http://kimihe.com/更新
引言
本章介绍汇编语言程序的创建过程,我们要准备踏上创作汇编程序之路啦~
仍旧如之前所说的,越了解底层,就越能够驾驭计算机。
摘要
- 所有的汇编过程都是处理文件的过程。
- 程序就是一个由非常小的步骤组成的漫长旅途,这些步骤是一个代表机器指令的二进制值的列表。
二进制文件 vs. 文本文件
- 机器上文件可以分为:文本文件(text file)和二进制文件(binary file)。
- 二进制文件可以使用Linux命令:
> xxd file
来查看,你需要直到打印出来的内容各字段的含义。如下输出:
$ xxd aa
00000000: 610a 620a 630a 640a 650a 660a 670a 680a a.b.c.d.e.f.g.h.
00000010: 300a 310a 320a 330a 340a 350a 360a 370a 0.1.2.3.4.5.6.7.
00000020: 380a 390a
可以看到输出有三列,最左侧的00000000等数字代表偏移量,它包含显示那一行的第一个字节与文件开头的第一个字节的偏移量。中间的以字节为单位显示16进制内容。最右侧显示可视化文本字符,对于不可显字符的二进制值采用句号字符表示。
- 注意到其中夹杂的0AH,这里它代表换行,对应键盘的enter(return)。值得一提的是在windows中,这个按键会产生回车(0DH)+换行(0AH),而Linux中只有换行(0AH)。现在大多数计算机系统和软件忽略回车,这是当年机械打字机的历史遗留:当打字机一行打满后,你必须把游标移到行首(回车0DH),并切到下一行(换行0AH),这样才能开始新一行的输入。
- 在一个二进制可执行文件中,位模式可能意味着完全不同的内容,这取决于它刚好位于文件中的位置,以及该文件中,它附近存在这哪些其他位模式。
字节序
- 对于字节顺序的解释可以分为小端法(little endian)和大端法(big endian)。一旦使用不止一个字节来代表一个数字值,字节的顺序就变得至关重要。
- 将多字节值的最低有效字节存储到最低偏移位置的计算机体系结构称为小端系统(little endian)。反之,将多字节值的最高有效字节存储到最低偏移位置的计算机体系结构称为大端系统(big endian)。
- 在大端系统中的数据以16进制显示很容易,因为它们按照人们期待的顺序出现,最重要(高位)的数在左边。而在小端系统中,一切都是颠倒的。
- 字节排列顺序的差异不仅适用于存储在文件中的字节,而且也适用于存储在内存中的字节。而最近的硬件体系结构都被设计为双向字节。
编译器
- 汇编语言具有非常重要的特征,正是这一点,使它在众多的编译器中与众不同,即:完全控制目标代码。
- CPU有很多机器指令,其中每一条都有一个对应的汇编语言助记符。
- 助记符和它的操作数整合在一起称为指令(instruction)。
目标代码和连接器
- 现代汇编编译器产生的目标代码文件是一种源代码和可执行文件之间的中间步骤,这个中间步骤是一种叫作目标模块(object module)的二进制文件。
- 目标代码文件本身并不能作为程序运行,还需要一个额外的必要步骤,那就是连接(link)。
- 目标代码文件作为中间步骤的原因是:大的源代码文件可以划分成许多更小的源代码文件,以保持文件大小和复杂性 的可管理性。
- 连接器不只是把目标代码块组合成一个单个的块,它确保模块以外的函数调用能够到达目标对象模块,并且确保所有此类内存引用实际上指向它们期望引用的地方。
重定位能力
- 与现代8086一同引入的Intel体系结构内部有了很大的改进,从而使程序无须被编译为在特定的物理地址运行。可知行文件内部的所有引用都通过相对于该程序起始位置的偏移量来指定。
- 偏移量总是相同的,并且因为所有的引用都是相对于可知行程序文件的起始位置,所以在运行时,程序放在物理内存中的什么地方都没有关系。
- 上述特性叫作可重定位能力。
感想
似乎是时候可以去亲手挑选硬件,并组装一台机器了说。
网友评论