我们的helloworld是从一个源程序开始的,该源程序由程序员通过编译器创建并保存的文件,文件名就是hello.c。这个hello.c的源程序,实际上是有0和1组成的序列。每一个0和1都成为一位,这些位被组织成8个一组,成为字节。文件组织形式是以ascii标准来表示文本字符,这种方式实际上就是用一个唯一的字节大小的整数值来表示每一个字符。Hello.c就是按照这样的字节序列来保存在文件中。像hello.c这样的只有ASCII字符组成的文件我们成为文本文件,所有其他文件成为二进制文件。

想要了解运行helloworld程序时发生了什么,就必须要了解计算机的体系结构。

计算机的硬件组成:

总线:

    贯穿整个系统的一组线。它携带信息字节并负责在各个部件之间专递。通常总线被设计成传送定长的字块,也就是一个字(word)。字中的字节数(字长)是一个基本的系统参数,我们常说的32位系统,64位系统就是这个意思。常用的是32位系统,4字节。总线中就是实际的32根线,一次向CPU传送32个0或者1。因为CPU是32位的,也就说CPU一次能够处理的数据是32个0或者1。

IO设备:

输入输出设备。常见的有鼠标键盘显示器。曾经的软盘,现在的光盘,以及U盘,移动硬盘等等。

主存储器

   主存储器是一个临时的存储设备,在处理器执行程序的过程中,它被用来存放程序和程序处理的数据。物理上来说,主存储器是由一组DRAM(动态随机存储器)芯片组成。DDR=Double Data Rate双倍速率同步动态随机存储器。严格的说DDR应该叫DDR SDRAM,人们习惯称为DDR,其中,SDRAM 是Synchronous Dynamic Random Access Memory的缩写,即同步动态随机存取存储器

处理器(cpu)

中央处理单元(CPU)的简称为处理器,是解释或者执行存储在主存中的指令。其中包含了若干寄存器,算术逻辑单元(ALU)。寄存器是很小的存储器,是有特定功能的存储器。例如PC寄存器,专门用来存储指令的地址,因为CPU执行指令的时候,需要知道在哪里取这个指令。

高速缓存机制:

由于机械的原因,我们的存储设备与cpu的读取速率差别巨大。我们不能让CPU执行一秒,等20秒来从磁盘中读取想要的数据。这样CPU的使用效率太低了,浪费资源。于是就有了高速缓存。高速缓存(cache )是位于CPU和主存储器之间,一次性从主存储器中存取整块数据,供CPU使用。提高CPU的运转效率。

存储设备的金字塔:

存储器的层次模型

在这个层次模型中,从上至下,设备变得更慢,更大,并且造价也更便宜。寄存器是在这个层次模型的最顶端,运行速率和CPU是一个数量级的。

执行helloworld程序

当shell程序执行它的指令,等待我们输入命令。当我们在键盘上输入字符串:./a.out后,shell程序就逐一读取字符到寄存器,再把它存放到存储器中。

keepalived二进制 二进制helloworld_数据

当我们在键盘上敲回车时,shell就已经知道我们已经结束了命令输入。然后shell执行一系列指令,这些指令将helloworld目标文件中的代码和数据从磁盘拷贝到主存,从而加载helloworld文件。

利用DMA(直接存储器存取)的技术,数据可以不通过处理器而直接从磁盘到达主存。

一旦helloworld目标文件中的代码和数据被加载到了存储器,处理器就开始执行helloworld的主程序中的指令,指令将“helloworld”字符串从存储器中拷贝到寄存器文件,再从寄存器文件拷贝到显示设备上,最终显示在屏幕上。


keepalived二进制 二进制helloworld_寄存器_02

keepalived二进制 二进制helloworld_keepalived二进制_03

操作系统:

我们的操作系统是用来帮助人们管理和使用计算机硬件资源的。我们使用的所有的软件都是运行在操作系统之上的。他们都使用操作系统提供的服务,而不会直接操作硬件。

虚拟存储器:

MMU是Memory Management Unit的缩写,中文名是内存管理单元。虚拟存储器是一个抽象概念,它为每个程序提供一个假象,好像每个进程都在独占使用主存。每个程序看到的存储器都是一致的,成为虚拟地址空间。在Linux中,最高的地址的四分之一的地址空间是预留给操作系统中的代码和数据的,对所有的进程都一样。底部的四分之三的地址空间用来存放用户的程序的代码和数据。

对于计算机内的信息存储:

大多数的计算机使用的是8位的块,叫做一个字节,来作为最小的可寻址的存储单位,而不是单独去访问存储器中的位。程序一般会将存储器视为一个非常大的字节数组,成为虚拟存储器。存储器的每个字节都由一个唯一的数字来标识,成为它的地址,所有可能的地址的集合就称为虚拟地址空间。具体是实现这个虚拟地址空间,实际上是由RAM(随机访问存储器)、磁盘、特殊的硬件和操作系统软件相互结合实现的。对于程序来说,就是一大片连续的地址空间。每台计算机都有个字长,字长决定了最重要的系统参数就是虚拟地址空间的最大的大小。也就是说,对于一个字长的N位机器而言,虚拟地址的范围就是0~2n-1,程序最多访问2n字节。当今计算机大部分是32位的,这就限制了虚拟地址空间为4GB。

寻址和字节顺序:

什么是地址?我们在存储器中如何对字节排序?在很多计算机上,多字节对象都被存储为连续的字节序列,对象地址是所使用的字节序列的最小地址。例如,假设一个类型为INT的变量X的地址为0x100,也就是说,地址表达式&X的地址为0x100。那么X的四字节被存储在存储器0x100,0x101,0x102,0x103的位置。

大端存储和小端存储:我们往一个int型的地址中存储数据,例如存储一个0x01234567。利用大端存储:


keepalived二进制 二进制helloworld_数据_04


keepalived二进制 二进制helloworld_寄存器_05

注意,在数据0x01234567中,高字节为0x01低字节为0x67。