Run Hello Program by Shell(通过Shell运行hello程序)
linux> gcc -o hello hello.c
上一讲中,我们讲述了hello程序如何经过编译系统得到可执行目标文件hello
此时可执行目标文件hello已经存放在系统的磁盘上,那么,如何运行这个可执行文件呢?
linux>./hello
在Linux系统上运行可执行程序。第一步,我们需要打开一个shell程序,然后在shell中输入相应可执行程序的文件名。
对于不熟悉linux系统的同学,可能对shell程序比较陌生。这里做一个简单的介绍,shell是一个命令解释程序,它输出一个提示符>来等待一个命令行的输入,然后执行这个命令。如果该命令行的第一个单词不是内置的shell命令,那么shell就会假设这是一个可执行文件的名字,对这个文件进行加载并运行。
在这个例子中,shell加载并且运行hello程序,屏幕上显示hello,world的内容,hello程序运行结束并退出,shell继续等待下一个命令的输入
hello程序运行时系统发生了什么
接下来我们看一下hello程序运行时系统发生了什么,不过在此之前我们先来
看一下计算机系统的硬件组成
计算机系统的硬件组成
中央处理单元
首先我们先大致介绍一下中央处理单元(Central Processing Unit,CPU),也称处理器。
实际上CPU的内部结构是非常复杂的。此处为了介绍hello程序的运行我们采用简化的框图来大概试一下整个CPU的结构。
程序计数器
首先我们看一下这个program count简称PC,很多中文资料将PC翻译成程序计数器。个人认为这种直译的方式并没有很好的表述PC的真实含义。这个PC实质上是一个大小为一个字的存储区域。
一个字是多大呢?对于32位的机器一个字是四个字,对于64位的机器,一个字就是八个字节。说白了PC就是一个字字节或者八字节的存储空间,里面存放的是某一条指令的地址。从系统上电的那一瞬间,直到系统断电,处理器就在不断的执行PC的指令。然后更新PC使其指向下一条要执行的指令。
注意:这个下一条指令与刚刚执行的指令不一定是相邻的。
寄存器文件
接下来我们看一下寄存器文件。它是CPU内部的一个存储设备。寄存器文件是由一些单字长的寄存器构成,每个寄存器都有自己唯一的名字。
通俗点儿讲,寄存器理解为一个临时存放数据的空间。例如我们计算两个变量a加b的和,处理器从内存中读取a的值暂存在寄存器x中。读取b的值,暂存在寄存器y中。这个操作会覆盖寄存器中原来的数值。
处理器完成加载的操作后,ALU(Arithmetic/logic unit,算术逻辑单元) 会复制寄存器x和y中保存的数值。然后进行算数运算,得到的结果会保存到寄存器的x或寄存器y中,此时寄存器中原来的数值会被新的数值覆盖。
主存
主存,也称为内存。处理器在执行程序时,内存主要存放程序的指令以及数据。从物理上讲,内存就是由随机动态存储器的芯片组成。从逻辑上讲,内存可以看成一个从零开始的大数组,每个字节都有相应的地址,(关于内存的更多详细内容。在第六章中会有详细的讲解。跳转)
内存和处理器之间通过总线来进行数据传递。实际上总线贯穿了整个计算机系统。它负责将信息从一个部件传递到另外一个部件。通常总线被设计成送固定长度的字节块,也就是字(word),至于这个字到底是多少个字节,各个系统中是不一样的;刚才我们也提到过32位的机器一个字长是4个字节,而64位的机器一个字长是8个字节。
除了处理器,内存以及总线,计算机系统还包含了各种输入输出设备。六,键盘,鼠标,显示器以及磁盘等等每一个输入输出设备。都是通过一个控制器或者设备器与io总线相连。控制器与适配器的主要区别在于它们的封装方式,无论是控制器还是设备系,他们的功能都是在iOS设备与总线之间传递数据。关于更多io的知识,我们将在第六章和第十章进行详细的讲解。前面介绍完计算机系统的硬件组成之后,我们现在开始介绍,当程序执行的时候到底发生了什么?首先我们通过键盘输入点杠hello的字符串图中闪烁的hello字符串表示键盘输入。要程序会将输入的字符逐一读入寄存器。处理器会把hello这个字符串放入内存中,整个流程如图所示。当我完成输入按下回车键时,shell程序就知道我们已经完成了命令的输入。然后推行一系列指令来加载可执行文件,哈喽,这些指令中的数据和代码从磁盘复制到内存。数据就是我们要显示输出的hello world感恩。这个复制过程,他利用dma技术数据可以不经过处理器从磁盘直接到达内存。当可执行文件hello中的代码和数据被加载到内存中,处理器就开始推行慢函数中的代码。我们的曼函数非常简单,又一个打印功能。CPU会将hello world感恩一个字符串从内存复制到寄存器文件。然后再从计算机文件复制到显示设备,最终哈喽,我的显示在屏幕上。对第一张的整体概述,读者只需要了解一个大概过程就可以。上述的描述过程中省略了一些细节,我们会随着不断的学习,在后续的课程中把所有的细节逐渐完善。从hello程序的执行过程来看,系统及时执行如此简单的程序数据信息仍然需要在磁盘内存,处理器以及io设备之间进行搬运。数据从一个地方搬运到另外一个地方需要花费时间,系统设计人员的一个主要任务就是缩短信息搬运所花费的时间。通常情况下,大容量的存储设备的存储速度要比小容量的慢。运行速度更快的设备的价格相对于低速设备要更贵,例如在一个系统上。磁盘的容量一般为tb,内存的容量一般为几比几?磁盘的容量大概是内存的1000倍,对于处理器而言,从磁盘上读取一个字所花费的时间开销要比从内存中读取的开销大1000万倍。寄存器文件只能存储几百个自己的信息。而内存可以存放几十亿之间的信息。处理器从寄存器文件读取数据比从内存读取数据差不多快100倍。随着半导体技术的发展,处理器与内存之间的差距还在持续增大对处理器和内存之间的差异。系统设计人员在寄存器文件和内存之间引入了高速缓存比较新的,处理能力比较强的处理器。一般有三级高速环境分别为l一开始,l二开始以及l三开始。L一开始的访问速度与访问计算器文件几乎一样快,容量大小为数万字节。偶尔开始的访问速度是l一的五倍,容量大小为数10万到数百万字节之间。L3开始的容量更大,同样访问速度与l2开始相比也更慢。因此整个计算机系统的信息存储可以用一个层次结构来表示。从这个层次结构来看,从上到下设备的访问速度越来越慢,容量越来越大。每次节都造价也越来越便宜。这个城市结构的主要思想就是上一层存储设备,是下一层存储设备的高速缓存。例如计算器文件就是l1的高速缓存。L1和l2的高速缓存,内存是磁盘的高速缓等等。程序员《深入理解计算机系统》,那么高速缓存黑利用存储器的层次结构来提升程序的性能。关于缓存的更多内容将在第六章中有更加详细的讲解。今天的视频就到这里,我们下期见。