计算机系统漫游

不了解土壤的组成成分,就很难种出可口的蔬菜;不了解操作系统,也不太可能写出高效优雅的程序。

我们先编写一段程序:

#include<stdio.h>int main(){   printf("hello world");}

保存为hello.c,然后我们编译、链接生成可执行的目标程序。当我们执行这个目标程序时,控制台会输出“hello world”。想不想知道程序运行时操作系统发生了什么?以及为什么会这样?

 

先别急,我们先搞清楚一个概念,“什么是文本文件,什么是二进制文件”?

 

我们知道,计算机的存储和计算都是基于0和1,如果我们想存储"#",该怎么办呢?毕竟计算机只能识别0和1,那我们能不能用不同的01组合代表这个字符呢?当然可以,这种组合方式我们就称它为"编码"。举个例子,我们用"100011"(十进制35)表示"#"

 

通过对比编码表,我们的hello.c源程序露出了它的本来面目

 

我们就把这种由ASCII字符构成的文件称为文本文件,所有其他文件都称为二进制文件。还有个简单的方法来判断,打开全是乱码的就是二进制文件,不是乱码的就是文本文件。

 

言归正传,我们编写的hello.c文件属于源文件,并不能做什么事情,需要经过以下几个步骤将其变为可执行的程序:

1、预处理

#gcc -E hello.c -o pre_hello.i

(1)将所有的#define删除,并且展开所有的宏定义。说白了就是字符替换  

(2)处理所有的条件编译指令,#ifdef #ifndef #endif等,就是带#的那些 

(3)处理#include,将#include指向的文件插入到该行处 

(4)删除所有注释  

(5)添加行号和文件标示,这样的在调试和编译出错的时候才知道是是哪个文件           的哪一行 

(6)保留#pragma编译器指令,因为编译器需要使用它们

vim pre_hello.i

 

没有乱码,所以它是文本文件。

 

2、编译

#gcc -S pre_hello.i -o com_hello.s

(1)词法分析

(2)语法分析 

(3)语义分析 

(4)优化后生成相应的汇编代码

vim com_hello.s

这里还是文本文件。

 

3、链接

#gcc com_hello.s -o hello

生成可执行的程序hello

vim hello

已经是乱码了,这里就是二进制文件。

 

我们来运行下这个可执行程序hello

#./hello

前面扯了那么多,那么可执行程序hello执行的时候,后台发生了什么?讲到这儿我们就需要画一个系统的硬件组成图了,一图胜千言。

 

I/O总线:传递字节的管道,计算机的数据都是由0和1构成,这个总线就负责传输01字节。如同一箱一箱的传送货物,I/O总线传输的也是定长的字节块,有的系统是4字节,32位,有的系统是8字节,64位(一个字节8bit)。

I/O设备:作为用户输入的鼠标和键盘,作为用户输出的显示器,以及磁盘都属于I/O设备,每个I/O设备都通过控制器或者适配器和I/O总线相连。这里插一个知识点,控制器和适配器有什么不同?控制器是置于I/O设备本身或者主板上的芯片组,而适配器是一块插在主板插槽上的卡,适配器可以很方便的插拔替换。它们的功能都相同,就是一个中介,在I/O总线和I/O设备之间传递信息。

主存储器:就是我们通常说的内存。

处理器:就是CPU中央处理单元。PC程序计数器,相当于一个指针,指向某条指令。每种CPU都有自己的指令集,操作都是在指令集的范围内操作。ALU算术逻辑单元,简单理解就是做算术逻辑运算的。工作的大致流程,先把内存的数据读取到寄存器,这一步称为加载,相当于把切好的菜放到炒锅里;然后寄存器把数据复制到ALU进行运算,置于是加法还是乘法或者其他,决定于从PC中读取的指令,并且运算后,将数据再复制到寄存器,这一步相当于炒菜添加油盐酱醋,俗称操作;最后是将数据由寄存器复制到内存,俗称存储,相当于把菜盛到盘子里。

 

概念讲完了,下面来看下程序运行时,计算机内部都发生了什么?

#./hello

在键盘上输入./hello后,shell会将hello这几个字符逐一读入CPU内部的寄存器,然后再把它存到内存(主存储器)。

之后shell执行指令将hello文件的内容加载到内存,因为文件是存储在磁盘上的,这一步操作属于从磁盘读取数据加载到内存。这里讲一个概念DMA(直接存储器存储技术)。上一步中,在控制台输入hello字符后,数据是先被读取到CPU的寄存器中,之后再由寄存器复制到内存。直接存储技术 就是省略数据加载到寄存器那一步,直接由磁盘传输到内存。

现在hello程序已经有磁盘传输到内存了,之后CPU将开始执行hello的二进制指令,这些指令将"hello world\n"中的字节由内存复制到寄存器,再从寄存器复制到显示设备,最终显示在屏幕上。

至此程序执行完成!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值