1.引言

前面我们已经提到过寄存器以及cpu的一些基本工作原理,那么在一个程序运行时,寄存器、cpu、内存等都是担任着怎样的角色呢?我们学习汇编的目的就是为了更好的了解计算机底层是如何工作的,所以我觉得有必要在学习汇编指令之前谈一谈一个计算机程序是如何在计算机上运行起来的。本文会尽可能详细地描述从写一个源程序到它被执行的过程中都计算机内部都发生了哪些事情。

2.计算机是如何工作的呢?

从宏观上来讲,计算机是给人提供服务的,提供方便的。人类想要告诉计算机一些东西,通过什么途径呢?输入设备(如鼠标,键盘,等等);计算机想要告诉人类一些东西也会通过输出设备(如屏幕,打印机,等等);计算机在读入用户的数据后,会对数据进行计算加工,这时会用到运算器;而运算的结果可能不会立刻输出给用户,而是暂存起来,这时计算机会用到存储器;而不论是运算的过程还是存储的过程,逻辑流程的安排,步骤序列则需要控制器。人类与计算机的交互,就是通过这五大部件的通力合作展开的,或者说,计算机的工作就是通过这五大部件实现的。

现代计算机基本上都是遵照冯·诺依曼体系结构进行设计、生产建造的。而该体系结构的核心概念就是存储程序计算机,即存储在计算机中的程序的执行,是通过一条条指令的执行而实现的(三阶段:取指令、指令译码、执行指令)。这是我们从微观的角度来看待计算机是如何工作的。
-------------摘自计算机是如何工作的

3.源程序到目标程序的过程

1.源程序的存储

我们就拿大家最熟悉的程序hello world来描述这个过程。


相信读者知道计算机是以0、1串来表示数据的,所以我们的hello world程序在计算机中也是以这样的形式存在的,8个位为一个字节,一个字节表示程序中的某些字符,也就是每个字符对应一个8位的整数值,这个整数值就是ascii码。
所以我们的源程序用ascii码就是这样表示的:

现在这些ascii码都是十进制方式展示在我们面前,但是在计算机当中还是一串串0、1组成的8位的串。这种以ascii码保存的文件就是文本文件,其它方式保存的文件都是二进制文件。

2.源程序的编译
虽然我们能够很轻松地看懂源程序,但是计算机却不能理解这些是什么东西,更不要谈运行我们的hello.c了,所以必须要让计算机也能看懂我们的意思,这时候就需要编译系统来帮忙了。

  1. 编译系统的作用:将源程序翻译为一些计算机能够理解的低级机器指令。
  2. 编译系统的组成:预处理器、编译器、汇编器、连接器
    编译系统的工作流程:

1.预处理器:根据以#开头的命令,修改源程序。如根据#include stdio.h>行,预处理器读取系统头文件stdio.h中的内容,代替此行内容。源程序经过预处理后,得到另一个c程序,此程序通常以.i为后缀保存。


2.编译器:将预处理后的.i文件转换成汇编程序。编译器将不同的高级语言(如c语言,C++语言)转换成严格一致的汇编语言格式进行输出。汇编语言以标准的文本格式确切的描述每机器语言指令。编译器得到的文件通常以.s为后缀保存。


3.汇编器:将汇编语言(.s文件)翻译成机器语言指令,并将这些指令打包成一种可定位目标程序格式。汇编后得到的文件即为二进制文件,通常以.o为后缀。


  1. 链接器:hello,world程序中调用过printf函数,它是一个c标准库里的函数。Printf函数存放在一个名为printf.o的单独预编译的文件中。而这个文件必须以适当的方式并入到我们的程序中,这个工作由链接器完成。将外部的.o文件并入后,得到一个完整的hello,world可执行文件。可执行文件加载到存储器后,由系统复制执行。

在unix系统中,源程序到目的程序的转换室友编译器驱动程序执行的。
输入命令:gcc hello.c -o hello
就会执行上述步骤并生成目标二进制程序。

4.运行目标程序

现在我们已经有了目标程序了,是时候运行了。
在unix系统中输入程序名:
当用户输入一行命令后,shell先判断它是不是一个shell内置命令,如果不是,shell会假定用户输入为一个可执行文件的名字,从而去加载并执行该文件。
注:

源程序是放在磁盘中的。
加载:把一个字节或一个字从主存复制到寄存器,覆盖掉寄存器中原来的值。

现在我们来关注下细节,计算机硬件到底做了什么?

上图是计算机一些基本的硬件组成。
其中一些硬件需要特别说明:

1.总线:在各个部件之间传输数据。

2.I/O设备:IO设备是系统与外界通信的通道,如鼠标,键盘,显示器,磁盘都是典型的IO设备。

3.主存储器:简称主存,是处理器执行程序时用于临时存放程序及其数据。主存由一组动态随机存储器芯片组成。也就是我们通常说的内存,它是与磁盘不一样的东西,就是我们计算机中的内存条

4.处理器:也就是cpu,解释执行存储在主存中的指令。其内部的pc永远指向下一条将要被执行的指令的地址。处理器的操作主要是围绕PC、ALU(算术\逻辑运算单元)、主存来进行运作的


CPU按照指令可能会执行的操作有:

加载:把一个字节或一个字从主存复制到寄存器,覆盖掉寄存器中原来的值。

存储:把一个字节或一个从寄存器复制到主存,并覆盖主存中原来的值。

操作:把两个寄存器的内容复制到ALU,ALU对两个字做算术运算后存回其中的一个寄存器,该寄存器中原来的值会被覆盖。

跳转:从cpu执行的指令抽取一个字的内容存入PC,覆盖掉原来的值,从而改变下一条要执行的指令,达到跳转的目的。

最开始shell程序处于执行状态,等待用户输入命令。当我们在shell环境下输入“.\hello”时,输入的字符被一个个读入寄存器并送入主存。

按下回车后,shell程序知道我们已经输入完成。
由于我们的可执行文件是放在磁盘里的。所以接下来要做的就是把磁盘的代码和数据复制到主存储器中(通过DMA方式加载程序,则不需要通过CPU,而是将hello可执行文件直接从磁盘复制到主存),如下图

可执行程序加载到主存后,cpu就执行hello程序的机器指令,而这些指令完成的工作便是将”hello,world\n”这几个字符从主存中复制寄存器文件中(register file),再将其从寄存寄文件中复制到显示设备上进行显示,如图:

到此,hello world程序从源程序到成功执行整个流程已经完成了。

5.拓展

1.高速缓存

其实上面的硬件组成并不符合现在的计算机,从上文可以看到内存是直接与寄存器进行数据交换的,这样其实是很浪费资源的,因为现在的cpu的处理速度非常快,但是对内存的读取与其比起来就显得特别慢,如果寄存器直接与内存打交道,效率就会很低,所以前辈们引入了高速缓存(cache)。高速缓存是寄存器与主存的一个过渡,也结合了两者的优点。高速缓存可以存放比寄存器多的数据,读取速度又快于主存。所以很多需要频繁使用的数据就可以放在cache中,这样就不用每次都去访问主存,大大提高了效率。
后来这种在较快的处理器与较大较慢的存储器之间插入一个过渡设备的思想得到了普及,就形成了后来的存储器分层结构:

2.操作系统管理硬件

在我们的hello程序中,我们都没有直接操作键盘、显示器、磁盘等,这些事情都是操作系统帮我们做了。操作系统其实就是介于硬件与我们的引用程序之间的一层软件。

操作系统有两大功能:

  1. 防止硬件被失控的程序操纵。
  2. 提供给应用程序提供操纵复杂的低级设备一个简单一致的方法。

每天进步一点点

汇编3-计算机程序是如何运行的相关推荐

  1. 计算机用户输入信息怎么保存,计算机中的全部信息,包括输入的原始数据、计算机程序、中间运行结果都保存在存储器中...

    指南:计算机中的所有信息,包括输入的原始数据,计算机程序,中间运行结果和最终运行结果都存储在内存中. 介绍内存的基本概念和分类 一.什么是内存 内存是计算机系统中的一种存储设备,用于存储程序和数据.计 ...

  2. 计算机程序是怎样运行的-hello world程序运行原理

    关于<深入理解计算机系统> "这本书的中译名为"深入理解计算机系统",我非常,十分,以及百分之一百二十地不满意.我这么说的原因在于这个译法完全扭曲了书的本意. ...

  3. 计算机程序是怎样运行的

    关于<深入理解计算机系统> "这本书的中译名为"深入理解计算机系统",我非常,十分,以及百分之一百二十地不满意.我这么说的原因在于这个译法完全扭曲了书的本意. ...

  4. 【嵌入式开发】 ARM 汇编 (指令分类 | 伪指令 | 协处理器访问指令)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42408137  转载请著名出处 本博客相关文档下载 :  -- A ...

  5. Intel格式和ATT格式汇编区别

    一.AT&T 格式Linux 汇编语法格式<?xml:namespace prefix = "o" /> 在 AT&T 汇编格式中,寄存器名要加上 '% ...

  6. Linux汇编语法开发

    汇编语言的优点是速度快,可以直接对硬件进行操作,这对诸如图形处理等关键应用是非常重要的.Linux 是一个用 C 语言开发的操作系统,这使得很多程序员开始忘记在 Linux 中还可以直接使用汇编这一底 ...

  7. 汇编 div_Solidity汇编开发简明教程

    在用Solidity开发以太坊智能合约时,使用汇编可以直接与EVM交互,降低 gas开销成本,更精细的控制智能合约的行为,因此值得Solidity开发者学习 并加以利用.本文是Solidity汇编开发 ...

  8. 学习16位DOS汇编笔记

    ax       //是16位的寄存器,最大可以存65535 ah,al  //是8位的寄存器,最大可以存255 cs:ip  //指向程序下一条执行的指令 ds     //数据段寄存器 ss   ...

  9. ARM(IMX6U)裸机C语言版本LED驱动实验(汇编进入处理器SVC模式、SP堆内存、跳转main函数、链接起始地址)

    参考:Linux之ARM(IMX6U)裸机C语言LED驱动实验–驱动编写,编译 作者:一只青木呀 发布时间: 2020-08-11 11:20:17 网址:https://blog.csdn.net/ ...

  10. 运行地址与加载地址估计大部分人没弄明白~

    本文为[单片机步入嵌入式Linux]系列文章的第二篇,主要是跟大家讲解一下链接过程中几个地址的区分与理解~ 1 单片机存储分配 在玩单片机(以stm32为例)的时候会有RAM空间和ROM空间,RAM空 ...

最新文章

  1. 扩增子分析解读7物种分类统计,筛选进化树和其它
  2. SAP系统内部顾问如何培养
  3. SAP CRM one order Appointment table
  4. 信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂
  5. TensorFlow 2.0开发者预览版放出!上手尝鲜可以开始了
  6. ap_invoice_distributions_all到xla_ae_lines
  7. python替换img的路径为新的路径_python – Django |连接路径位于基本路径组件之外{%static img.thumbnail.url%},错误400与whitenoise...
  8. 如何在Mac上禁用通知预览?
  9. 关于bayes错误率计算公式P[error] = P[error | x]P(x)dx
  10. html+css+js实现注册页面
  11. 无纸化办公模式如何取代传统办公模式
  12. STM32外接DHT11显示温湿度
  13. 电力设备管理杂志电力设备管理杂志社电力设备管理编辑部2022年第14期目录
  14. 18[NLP训练营]拉格朗日乘子法、对偶、KTT
  15. 公积金能付首付吗?你在公积金贷款买房前这些知道吗?
  16. 思科服务器网关配置文件,思科服务器网关配置文件
  17. Microsoft Edge 和 Google Chrome更新后,出现错误代码:STATUS_STACK_BUFFER_OVERRUN,有效解决办法记录【已解决】
  18. PS A11选区和选框工具
  19. @Value的诸多用法
  20. 算法设计与分析第一章课后作业

热门文章

  1. 仙剑永恒的经典──仙剑诗集
  2. 程序化广告(2):程序化广告的参与者
  3. 你们天天说的应用性能监控: Sky Walking
  4. 拉丁舞身形研究之恰恰恰
  5. 科研必备之图像局部区域放大——画中画形式
  6. 爬虫爬取东方财富网的股票走势图
  7. ddos防火墙防御假人攻击测评
  8. python爬虫的知识
  9. uniapp 引入外部链接js
  10. mysql 库存超卖_mysql处理高并发,防止库存超卖