第一篇笔记的主题是讨论Hello World程序的生命周期,程序是最简单的hello world程序,使用高级C语言编写。

先介绍整个生命周期中涉及到的几个部分以及相应的概念,然后总结整个生命周期,最后是几个零散的知识点。

程序

#include<stdio.h>
int main(){
printf("Hello World!\n");
system("pause");
return 0;
}

编译系统

基于以下的几个疑问,我们有必要了解编译器如何工作:

  1. 优化程序性能 : 例如 一个switch语句是否比一串if-else语句高效?一个函数调用的开销有多大?while循环和for循环,哪个更有效?
  2. 理解链接时出现的错误 :链接器报告它无法解析一个引用,这是什么意思?静态变量和全局变量的区别是什么?
  3. 避免安全漏洞 :缓冲区溢出错误如何产生?

下面针对Hello World程序,介绍一下编译系统如何工作。

  • 预处理阶段:预处理器(cpp)根据以字符#开头的命令,修改源程序;#include<stdio.h>告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入到源程序中,生成的文件以.i为扩展名。
  • 编译阶段  :编译器(ccl)将.i文件翻译成.s文件,这是一个汇编语言程序。汇编语言为不同高级语言的不同编译器提供了通用的输出语言。
  • 汇编阶段  :汇编器(as)将.s文件翻译成机器语言指令,并打包成可重定位目标程序,也就是.o文件。.o文件是二进制文件,它的字节编码是机器语言指令而不是字符。
  • 链接阶段  :链接器(ld)。printf函数是一个C标准函数,单独存在于一个预编译好的printf.o目标文件中,链接器将其合并到hello.o文件中,生成可执行文件,然后载入内存,等待运行程序。

此时,hello.c源程序已被编译系统翻译成了可执行目标文件hello,存放于磁盘上。需要运行时,用命令解释器(外壳(shell))运行。

计算机的几个相关硬件

  • 总线     :贯穿整个系统的一组电子管道,负责携带信息并在各个部件之间传递信息。传送定长的字节块(字),每个字的字节数(字长)因系统而异。
  • I/O设备:负责系统与外部进行信息交互。上图示例有四个I/O设备:鼠标键盘(用户输入)、显示器(用户输出)和磁盘(存储程序和数据)。每个I/O设备通过一个控制器或适配器与I/O总线相连,负责在两者之间传递信息。
  • 主存    :一个临时存储设备,在处理器运行程序时负责存放程序和程序处理的数据。
  • CPU   :负责解释(或执行)主存中的指令。处理器的核心是一个字长的存储设备(或寄存器),称为程序计数器(PC,注:PC区分“个人计算机”)。任何时刻,PC都指向主存中某条机器语言指令,即PC中存放该指令的地址。从系统通电开始,到系统断电为止,处理器就一直在执行PC指向的指令。执行完之后更新PC,在指向下一条指令,值得一提的是这里的下一条指令并非物理意义上的下一条,也即不一定与上一条指令相邻。这样的简单操作并不多,且围绕着主存、寄存器文件和算数/逻辑单元(ALU)进行,寄存器文件是一个小的存储设备,由一些1字长的寄存器组成,每个寄存器都有唯一的名字;ALU负责计算新的数据和地址。

CPU执行的操作

  • 加载:把一个字节或者字从主存复制到寄存器,并覆盖寄存器原来的值。
  • 存储:把一个字节或者字从寄存器复制到主存的某个位置,病覆盖掉主存该位置原来的值。
  • 操作:把两个寄存器的内容复制到ALU,ALU对这两个内容做算术运算,将结果存放到一个寄存器中,并覆盖掉原来的值。
  • 跳转:从指令本身中抽取一个字,复制到PC中,并覆盖掉PC中原来的值。

现在总结一下运行hello程序的整个过程:

  • 开始时我们先通过键盘鼠标等用户输入设备将高级语言源程序写入电脑,这些程序代码存储在磁盘上。
  • 然后编译系统将高级语言程序代码经过预编译、编译、汇编和链接等操作将C语言代码翻译成机器语言指令,存放在磁盘上。
  • shell等待我们输入一个指令,当我们从键盘输入字符串“./hello”后,shell将字符串逐一读入寄存器,然后存储到存储器。现在主存放着“hello”命令。如下图所示:

  • 当我们输入回车时,shell知道命令输入结束。然后执行一系列操作加载可执行的hello文件,将hello目标文件中的代码和数据从磁盘复制(操作)到主存,利用直接存储器存取(DMA)技术(后续讨论),数据可以从磁盘直接到达主存。现在主存放有运行程序的命令和运行程序所需的机器语言代码。如下图所示:

  • hello的代码和数据加载到主存后,处理器开始执行hello程序的main程序中的机器语言指令,这些指令将结果字符串“Hello World\n”以字节的形式从主存复制到寄存器,然后再复制到显示设备,最后我们在屏幕上看到”Hello World“。过程如下图所示:

以上就是hello world程序整个软硬件配合从输入到输出的整个过程。下面罗列几点上面用到的知识点。

  • 源程序实际上就是一个由值0和1组成的位序列。8个位组成一个字节,每个字节表示程序中的某个文本字符。hello.c程序以字节序列的方式在文件中进行存储。
  • 大部分的现代系统使用ASCII标准来表示文本字符,这种方式实际上使用一个字节表示一个字符。
  • 像hello.c这样只由ASCII字符构成的文件称为文本文件,其他的所有文件均称为二进制文件。

    以此类推:系统中所有的信息都是由一串位表示的,事实上的确如此。区分这些数据的唯一方式是读取这些数据时的上下文。
  • 从上面的过程可以看出,系统很多的时间花费在了信息转移传递的过程:hello程序的机器指令最初是在磁盘上的,当程序加载时,它们被复制到主存;当处理器运行程序时,它们又被复制到处理器。
  • 计算机系统是由硬件和系统软件组成的,他们共同工作来运行应用程序。

最后附上源程序的ASCII码图

深入理解计算机系统(1)--hello world程序的生命周期的更多相关文章

  1. 教你理解微信小程序的生命周期和运行原理

    转自:http://blog.csdn.net/tsr106/article/details/53052879  写微信小程序,他的生命周期不能不知道,不知道小程序就会出现各种bug而无法解决.小助君 ...

  2. 理解微信小程序的生命周期和运行原理

    写微信小程序,他的生命周期不能不知道,不知道小程序就会出现各种bug而无法解决.小助君公众号带你学习小程序的生命周期和运行原理. 小程序由两大线程组成:负责界面的线程(view thread)和服务线 ...

  3. asp.net MVC 应用程序的生命周期

    下面这篇文章总结了 asp.net MVC 框架程序的生命周期.觉得写得不错,故转载一下. 转载自:http://www.cnblogs.com/yplong/p/5582576.html       ...

  4. 浅析 - iOS应用程序的生命周期

    1.应用程序的状态 状态如下: Not running  未运行  程序没启动 Inactive          未激活        程序在前台运行,不过没有接收到事件.在没有事件处理情况下程序通 ...

  5. iOS 应用程序的生命周期

    iOS 应用程序的生命周期(网络资源总结) http://blog.csdn.net/totogo2010/article/details/8048652 http://www.cocoachina. ...

  6. ASP.NET 应用程序(Application)生命周期概述

    原文:ASP.NET 应用程序(Application)生命周期概述 引用MSDN:ASP.NET 应用程序生命周期概述 本 主题概述应用程序生命周期,列出重要的生命周期事件,并描述如何编写适合应用程 ...

  7. [转]iOS 应用程序的生命周期

    OS的应用程序的生命周期,还有程序是运行在前台还是后台,应用程序各个状态的变换,这些对于开发者来说都是很重要的. iOS系统的资源是有限的,应用程序在前台和在后台的状态是不一样的.在后台时,程序会受到 ...

  8. [转] 微信小程序之生命周期

    本篇文章介绍小程序的生命周期,由于小程序分为应用和页面两个部分,所以小程序的生命周期就涉及到三个部分,分别是: 应用的生命周期 页面的生命周期 应用的生命周期对页面生命周期的影响 一.应用的生命周期 ...

  9. 小程序的生命周期 launchApp

    https://developers.weixin.qq.com/miniprogram/dev/api/launchApp.html?search-key=生命周期 launchApp(OBJECT ...

随机推荐

  1. 给于用户Agent权限设置

    问题:有一个用户需要有create\alter\drop job人权限.默认是只有sysadmin成员才有这个权限.肯定不能将用户放到这个组 答案:所有JOB都属于msdb库中读取和写入信息.所以,肯 ...

  2. 从命令行运行Jmeter及jmeter参数说明、Html报告生成

    为什么要命令行执行脚本,主要有以下三点: 1) 图形化界面消耗更多资源,CPU和内存 2) 图形化界面不支持大型的负载测试和性能测试 3) 命令行测试支持持续集成,例如放到Jenkins这样的CI工具 ...

  3. php 引用变量

    什么是引用: 官方给的解释是:用不同的名字访问同一个变量内容. 1.普通的变量 运行之后内存空间变化是这样的: 2.引用变量 运行之后内存变化是这样的: 几乎没有什么变化. 3.使用unset 销毁的 ...

  4. 中小学信息学奥林匹克竞赛-理论知识考点--IP地址

    IP地址同身份证号一样,具有唯一性! 每个人都有一个唯一的标识:身份证号. 互联网中的计算机也一样,具有一个唯一的标识:IP地址. IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也 ...

  5. 任务学习-ucos

    1.任务(task)也称作一个线程: 2.一个任务有5种状态:休眠,就绪,运行,挂起,被中断 休眠:任务驻留在程序空间中,还没有交给ucos管理,把任务交给ucos 是通过调用OSTaskCreate ...

  6. VSTO Project 客户端自动发送邮件

    利用office vsto功能,抓取我们选择的任务,根据配置节,邮件发送内容,最终根据任务名称,任务开始结束时间,任务资源名称,发送邮件给任务资源. 这是我的VSTO界面. 配置我们发送邮件的服务器地 ...

  7. Oracle闪回恢复误删除的表、存储过程、包、函数...

    在日常的数据库开发过程汇总难免会出现一些误删除的动作, 对于一些误删的操作我们可以通过oracle提供的闪回机制恢复误删数据, 从而避免出现较大的生产事故. 下面是本人平时工作中积累的一些常用的操作, ...

  8. [HNOI2003]操作系统(优先队列,堆排序)

    题目描述 写一个程序来模拟操作系统的进程调度.假设该系统只有一个CPU,每一个进程的到达时间,执行时间和运行优先级都是已知的.其中运行优先级用自然数表示,数字越大,则优先级越高. 如果一个进程到达的时 ...

  9. string类中字符的大小写转换

    今天做一道题,要用string类,涉及大小写转换,查看了C++文档,string类没有提供这样的方法,只好自己写. 之后是想到一个比较笨的方法,我把string当成一个容器,然后用迭代器一个一个来替换 ...

  10. Flask中异常捕获

    HTTP 异常主动抛出 abort 方法 抛出一个给定状态代码的 HTTPException 或者 指定响应,例如想要用一个页面未找到异常来终止请求,你可以调用 abort(404). 参数: cod ...