计算机系统是由硬件和系统软件组成的,它们共同工作来运行应用程序。当你在系统上执行用C编写的 hello 程序时,系统发生了什么以及为什么会这样那?
准备
hello.c 程序
# include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
信息就是 位+上下文
hello.c 程序以字节序列的方式储存在硬盘上的(简单的说就是一串 1,0 的序列)
hello.c 的表示方法说明了一个基本思想:系统中所有的信息 – 包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传输的数据,都是由一串比特表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如,在不同的上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串活着机器指令。
程序被其他程序翻译成不同格式
hello 程序的生命周期是从一个高级 C 语言程序开始的,因为这种形式能够被人读懂,然而,为了在系统上运行 hello.c 程序,每条 C 语句都必须被其他程序转化为一系列的低级机器语言
指令。然后这些指令按照一种称为目标程序
的格式打好包,并以二进制的形式存放在磁盘上。目标程序也称为可执行目标文件
。
linux> gcc -o hello hello.c
GCC 编译器驱动程序读取源文件 hello.c, 并把它翻译成一个可执行的目标文件 hello。这个翻译的过程分为四个阶段完成,如下图所示。执行这四个阶段的程序(预处理器
、编译器
、汇编器
和链接器
)一起构成了编译系统
。
了解编译系统如何工作的好处
- 优化程序性能
- 理解链接时出现的错误
- 避免安全漏洞
处理器读并解释
储存在内存中的指令
- 系统的硬件组成
- 总线
- I/O 设备
- 主存
- 处理器
- 运行 hello 程序
初始时,shell 程序执行它的指令,等待我们输入一个命令。当我们在键盘上输入字符串“./hello”后,shell 程序
将字符逐一读入
寄存器,再把它存放到内存中。
当我们在键盘上敲回车键时,shell 程序就知道我们已经结束了命令的输入。然后 shell 执行一系列指令来加载可执行的hello 文件,
这些指令将 hello 目标文件中的代码和数据从硬盘复制到主存。数据包括最终回输出的字符串“hello, world\n”。(利用直接存储器存取
(DMA)技术,数据可以不通过处理器而直接从磁盘到达主存)
一旦目标文件 hello 中的代码和数据被加载到主存,处理器就开始执行 hello 程序的 main 程序中的机器语言指令。这些指令将“hello,world\n”字符串中字节从主存复制到寄存器中,再从寄存器文件复制到显示设备,最终显示在屏幕上。
高速缓存
主存主要负责存储指令和数据,而 CPU 所执行的指令和数据都是从内存中读取的。针对处理器与主存之间的差异,系统设计者采用更小更快的存储设备,成为高速缓存存储器。这样就可以了将一些带执行的指令和数据放到高速缓存存储器。
存储设备形成层次结构
操作系统管理硬件
在hello程序的例子中,shell 和 hello 程序都没有直接访问键盘、显示器、磁盘或者主存。取而代之的是,它们
依靠操作系统
提供的服务。我们可以
把操作系统看成是应用程序和硬件之间插入的一层软件。
操作系统有两个基本功能:1.防止硬件被失控的应用程序滥用;2.向应用程序提供简单一直的机制来控制复杂而又大不相同的低级硬件设备。
-
进程
进程
是操作系统对一个正在运行的程序的一种抽象。 -
线程
在现代系统中,一个进程实际上可以由多个称为线程的执行单元组成,每个线程都运行在进程的上下文中,并共享同样的代码和全局数据。
-
虚拟内存
虚拟内存是一个抽象概念,它为每个进程提供了一个假象,即每个进程都在独占地使用主存。每个进程看到的内存都是一致的,称为虚拟地址空间。
-
文件
文件就是字节序列。每个 I/O 设备,包括磁盘、键盘、显示器,甚至网络,都可以看成是文件。Unix 设计哲学:万物皆文件。
系统之间利用网络通信
对操作系统来说,网络也是一种 I/O 设备,如下图
转载:https://blog.csdn.net/melody_lql/article/details/98972047