程序是如何跑起来的

A说:鼠标双击下不就跑起来了啊

B说:./xxx 这样程序就能起来了。

两者的回答都是在用户角度看到的现象,但是内部机制是什么样的呢?

一、计算机

      

最早的输入输出设备并不是键盘和显示器,而是打孔卡和打印机。用打孔卡来作为机器指令的输入,早在 18 世纪初就被用在织布机上了。早期的数字计算机就是用打孔卡来表达程序指令和输入的数据。

下图是 IBM 制造的打孔卡:

 

 

       电子计算机的问世,奠基人是英国科学家艾兰· 图灵(Alan Turing)和美籍匈牙利科学家冯· 诺伊曼(John Von· Neumann)。图灵的贡献是建立了图灵机的理论模型,奠定了人工智能的基础。现在上了英国货币50英镑。而冯· 诺伊曼则是首先提出了计算机体系结构的设想。冯.诺伊曼体系结构是现代计算机的基础,现在大多计算机仍是冯.诺伊曼计算机的组织结构,只是作了一些改进而已,并没有从根本上突破冯体系结构的束缚。冯.诺伊曼也因此被人们称为“计算机之父”。

 

二、操作系统

     windows,linux,unix,macOS,Android。

    目前系统有32位和64位区分。为什么没有48位的系统?这个跟计算机使用二进制表示有关系,所以32X2=64.

    我们办公用的系统是64位的,32位的系统只能支持4G内存,64位理论上能支持很大很大的内存。

    在计算机中尚不存在操作系统的年代,完全没有任何程序,因此程序员就需要编写出处理相关操作的所有程序,必须与硬件打交道。(AMC美剧:奔腾年代

     在洪荒年代,软件和硬件的边界还非常模糊,写程序也并不是一个纯软件的行为,把程序刻录到存储上往往还涉及了硬件的电气操作。

     为了解决编程效率的问题,汇编语言(和解释它的编译器)诞生了。汇编语言的编译器将汇编语言写的程序编译成为 CPU 指令序列,并将其保存到外置的存储设备(比如硬盘)上。

     汇编语言非常接近计算机的 CPU 指令,一条汇编指令基本上和CPU 指令一一对应。在汇编语言出现后才有的操作系统。

     在编程的历史进程中,有程序员开发了监控程序,能在硬件上直接运行。于是,操作系统的原型(demo)就出来了。通过这个监控程序,程序员可以根据需要将各种程序加载到内存中运行。这个阶段,普通用户还是没法使用这个系统的,太麻烦,需要很多专业技能。

后面出现MS-DOS系统后个人电脑快速普及。现在的程序员写应用(软件)不再需要关注硬件,也不需要懂硬件了。内存大,固态磁盘读写速度快,cpu主频高,写程序就不必要纠结性能了(大部分是这个情况)。所以,现在的时代人人都可作出app/软件,成为程序员。从程序员进阶成软件开发工程师,就需要了解些硬件和软件工程相关的了。

        操作系统的启动过程

      操作系统是怎么获得执行权的?这是计算机主板 ROM 上的启动程序(BIOS)交给它的。

        计算机加电启动后,中央处理器(CPU)会从一个固定的存储地址加载指令序列执行。通常,这个固定的存储地址指向计算机主板的 ROM 上的一段启动程序(BIOS)。这段启动程序通常包含以下这些内容。

      1. 存储设备的驱动程序,用以识别常规的外置存储设备,比如硬盘、光驱、U 盘。

      2. 基础外部设备的驱动程序,比如键盘、鼠标、显示器。

      3. 设备和启动配置的基础管理能力。

      4. 支持执行外置存储中引导区的机器代码程序。

      5.跳转到外置存储引导区的固定地址,把执行权交给该地址上的引导程序。

     引导区的引导程序有长度限制只能做非常少的事情。在常规情况下,它只是简单地跳转到真正的操作系统的启动程序,但有时计算机上安装了多个操作系统,此时引导程序会提供菜单让你选择要运行的操作系统。

      这样,操作系统就开始干活了。

     Unix

    1973年,Unix正式诞生于贝尔实验室。贝尔实验室的Dennis Ritchie将B语言重新改写成C语言,再以C语言重新改写和编译Unics的内核,最后发行了UNIX的正式版本。

    Linux

   Linux系统的诞生开始于芬兰赫尔辛基大学的一位计算机系的学生,名字为Linus Torvalds,因满足不了个人的使用需求,于是把Minix安装到了i386个人计算机上,开始了Linux系统雏形的设计和开发。

   1991年底,Linus Torvalds公开了Linux内核源码0.02版。1993年,Linux1.0版发行。

    MS-DOS

     当时的PC巨头IBM 没把操作系统当回事儿,把这个活儿包给了微软。然后是微软只花了 5 万美元向西雅图公司购买了86-DOS 操作系统的版权,更名为 MS-DOS。(86-DOS是西雅图公司的一个 24 岁小伙叫蒂姆·帕特森(

Tim Paterson),单枪匹马花了 4 个月时间写出来的)

 

 

三、程序

     程序即应用、软件,存活于操作系统之上。操作系统的目标是软件治理,没有软件就没有操作系统存在的必要。

     windows的程序没法在linux下跑,也没法在macOS上跑。反之亦然。

    运行环境 = 操作系统 + 硬件。

    程序中包含着运行环境这部分描述,像App Store中还有系统版本描述,版本过低的还没法运行。

    在苹果使用Intel的cpu后,mac笔记本可以装windows系统。但是,安卓机没法装苹果系统,硬件不一样,尤其是CPU。

     x86、MIPS、SPARC、PowerPC等不同架构的CPU的机器语言是不一样的,某个CPU只能解释自己的机器语言。一般操作系统使用C语言开发,C语言是汇编语言的语法糖,比用汇编编写来的友好很多。但是,C语言写的代码

编译后最终还是会转成汇编。后面出现了java虚拟机,采用java语言编写的代码就能轻松实现跨平台运行。因为程序是跑在了虚拟机里。只要在对应系统中能装上java虚拟机就行了。所以,java大行其道。在java语言编写的程序运行时,java虚拟机将编译后的字节代码转换成本地代码,这样的操作是把双刃剑。(优:同样的字节代码在不同的环境下运行;劣:每次运行的代码转换降低了速度)

     操作系统的文件是在硬盘中,在我们点下开机按键时候,电流会激活主板。BIOS会确认硬件是否正常运行,没有问题的话就会启动引导程序。就是开机界面会出现黑底白字的那一幕。我们可以设置先读取CD-ROM,还是U盘,还是硬盘。如果系统装在U盘中,设置优先读取U盘的话,就会加载U盘中的OS系统到内存中运行。OS系统不能自启动,只能通过引导程序来启动。OS启动后,我们就可以在上面启动应用程序了。

     OS很多是用C语言写的,但是应用开发的语言有很多种。以windows下c语言编写应用为例,先写一个代码文件,也就是文本文件;使用c编译器把源码文件编译成目标文件(.obj);最后链接器会从库中抽取出必要的目标文件并将其结合到EXE文件中。那这个EXE文件中的内容就是机器能识别的语言。但是,我们右键打开看到的却是一堆乱码。我们平时说的集成开发环境是包含了编译器和链接器,如visual studio和gcc。

    因为程序是加载到内存中运行的,所以我们才需要很大的内存。要不然程序开不了几个就卡了。程序是通过调用OS的API来实现跟硬件的交互的。

    内存泄漏(Memory Leak):程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

    如果某个程序使用一段时间后,发现变慢了,可能就有内存泄露。

posted @ 2019-07-16 20:57  超龄码农  阅读(1016)  评论(0编辑  收藏  举报