众所周知,对于冯·诺依曼体系结构的现代计算机而言,主要的组成部分是:cpu、内存和I/O。作为电子元器件,cpu和内存识别二进制中的1和0都是通过电压的有无来实现的,因此电压在有无之间变换频率的快慢或者说这些元器件能识别这些变换频率的能力直接影响着计算机处理数据的能力。

    CPU

    犹如人体的大脑一样,cpu在整个计算机的运行过程中起着至关重要的作用,这些作用包括计算功能和控制功能。然而,就像吃饭时要有一个器具盛米饭一样,当CPU进行计算的时候,必须有一个类似的容器,当表示第一个数据的比特(电压)流消失以后能够将其缓存起来与下一个数据做运算,这个安放在CPU里面的容器就叫做寄存器,实现运算功能的部件叫做运算器。当然,对于计算机内部的元器件来说,要想实现数据的处理必须经过CPU,因此CPU要有与各个部件相连的通道,为了让尽可能少的线部署在有限的空间里面,我们用一组线来贯穿整个计算机,所有的部件都与其相连,这组线称为:总线。对于这样的总线结构,必然存在协调收发的冲突检测和避免机制,就好像我们在车流量较大的主干道要有红绿灯来指挥交通一样,在计算机内部,这个指挥交通的元器件叫做控制器,其他部件上有一个接受控制器命令的控制单元。

    内存

    在计算机内部,CPU能直接访问的只有内存,因此CPU需要能精确的在内存中找到需要处理的数据,所以内存是编址的。一个内存被分为N个Cell,每一个Cell包含8bits并且都有一个地址,控制器通过地址总线连接到内存控制器,如果一个内存控制器输出32根线(32位),那么寻址能力就是4G.

    操作系统

    对于每一个硬件,它的运行规格不一样,比如:不同厂商的CPU对于机器码的识别方式不同,可能相同的0和1组合一个表示加,一个表示减。于是对于早期的程序员来说要想实现一个应用程序的逻辑必须了解开发平台上所有硬件的机器码识别方式,这一点是非常困难的。同时厂商千千万,在一个特定硬件组合平台上开发的程序不可能移植到其他的硬件平台上,要解决这个矛盾必须开发一个中间层,向下能驱动所有的硬件设备,向上提供统一标准的接口,通过这个统一的接口来驱动底层硬件的过程称为系统调用(system call),这个中间层通俗的称呼是:操作系统,在Linux中叫做Linux内核。

    操作系统提供了应用程序和底层硬件交互的平台,它能够驱动所有的底层硬件,同时最重要的是能够通过分时的方式管理CPU,让各个应用程序协调工作。虽然都是中间层,但是Linux和windows向上提供的统一接口标准不同,所以一个应用程序根据操作系统的不同会有windows32/64和Linux32/64等几个版本。

    API和ABI

    如前文所言,即使能够驱动不同厂商的硬件,我们的操作系统(内核)的接口依然非常底层,比如word需要用到打印功能,excel也需要用到相同的功能,那么就需要把所有厂商的打印接口能实现的打印功能统一用一种通用规范表示出来,这些通用规范叫做:库。库提供向上的接口称为API,程序员通过API调用库。POSIX是是目前通用的API执行规范,由IEEE规定,兼容Windows和Linux,syscall和libcall属于API范围。

    应用程序直接运行在硬件上面,但是依赖于操作系统提供的环境,而且受制于操作系统的管理,这个环境称为:ABI。windows上的执行程序支持的是exe,msi格式,而Linux上支持的是ELF格式的,每一个应用程序都有一个执行入口,表明所支持的二进制格式。

    简而言之,在windows上开发的源程序,在Linux上能编译,需要两边的API要一样,在windows上开发在windows上编译在Linux上要能运行,两边的ABI要一样。