2021年11月27日准备发在基地微信公众号上的推文。

综合了多篇大佬的博客,以及自己已经知道的知识,对一些疑惑进行了现阶段我认为还算满意的解答。

不过又产生了很多疑问:

  1. 内存和磁盘的关系
  2. CPU是如何运行机器指令的(虽然大概想过去会是数字逻辑上的电路的组合)
  3. ......

========================================================================================================================================

我写的上一篇推文是:Vscode里的多文件编译,本来这一篇计划是多语言混编,可是还没玩太明白,就来补充讲一讲程序的运行过程,对上一篇也是一种补充。

当我们要让一个程序运行起来,如下面这段代码:

1 #include <stdio.h>
2 int main()
3 {
4 printf("Hello World\n");
5 return 0;
6 }

需要以下过程:

1. 预处理

 gcc -E hello.c -o hello.i 

这一过程主要是处理源代码文件中:

  • 以”#”开始的预编译指令

    如”#include”、”#define”等

    将include的文件插入进来,将所有define的宏定义展开。

  • 删除注释

  • 添加行号和文件名标识。

    以便编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号

2. 编译

 gcc -S hello.i -o hello.s 

编译程序(Compiler)把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件。

当然,预处理和编译可以合二为一,直接一步到位:

 1 gcc -S hello.c -o hello.s 

这里提一下这个gcc,这只是后台编译程序(compiler)的控制台,会根据不同参数去调用不同的预处理、编译程序,来处理不同的语言。

3. 汇编

 1 gcc -c hello.c -o hello.o 

.o文件就是“目标文件”(Object File),将汇编语句转换为机器语言,机器语言是CPU可以执行的命令。

4. 链接

在上面的过程中,原本的一个文件会生成若干个目标模块,这些模块是割裂的。

由链接程序(Linker)将这些目标模块(程序段),以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load Module);这是完整的执行命令的可执行文件exe(此时已经是二进制文件)。

链接分为静态链接和动态链接。不展开了。

DLL文件就是Dynamic Link Library文件.

5. 装入

可执行文件只有装载到内存以后才能被CPU执行。

装入过程就是由装入程序(Loader)将装入模块装入物理内存。物理内存就是真实存在的内存条。

物理内存是由若干个存储单元组成的,每个存储单元有一个编号,这种编号可唯一标识一个存储单元,称为内存地址(或物理地址)。

可以简单理解成类数组的一个结构。

这个过程进行了地址重定位,主要是将逻辑地址转换成物理内存的绝对地址(相当于拿考号找座位)。这个过程只有在程序将要被运行的时候才会发生。

6. 执行

执行不是一个严格的概念,只是我用来描述装入到输出“Hello World”这个过程的一个名词。

当计算机要运行该程序时,二进制文件中相关的指令会发送给CPU,经过CPU的操作,显示到了显示器上。

7. GCC

补充GCC的工具链

8 复习

  1. 程序从按下“编译”到装入内存需要哪些过程?
  2. GCC工具链有哪些?

计算机系统->Hello World的一生 | 程序如何运行的更多相关文章

  1. C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper

    前言 在开发应用程序时,通常只让程序运行一个实例.所以,就要判断程序是否已经运行. 下面是我自己在项目中使用到,封装好的帮助类.有 普通的 C# 应用程序 和 Windows CE 和 Windows ...

  2. C# Winform防止一个程序重复运行

    1: //在写一些服务型的软件的时候,你可能不希望一个操作系统里有两个副本在运行,这样也许会扰乱你的操作.这时,你就需要限制程序的副本.下面的这个方法,很简单的就可以实现上述功能. using Sys ...

  3. 关于SQL Server 安装程序在运行 Windows Installer 文件时遇到错误

    前几日安装sql server2008r2 的时候碰到这个问题: 出现以下错误: SQL Server 安装程序在运行 Windows Installer 文件时遇到错误. Windows Insta ...

  4. <<< php程序在运行后报“internal server error”错误

    上传的php程序在运行后报“internal server error”错误,检查以下两方面: 1.请您检查php程序的属性是否设置为755,如果php程序的属性不是755,那么运行的时候会报“int ...

  5. 如何利用 JConsole观察分析Java程序的运行,进行排错调优

    原文链接:http://jiajun.iteye.com/blog/810150 一.JConsole是什么 从Java 5开始 引入了 JConsole.JConsole 是一个内置 Java 性能 ...

  6. /var/run/yum.pid 已被锁定,PID 为 XXXX 的另一个程序正在运行。

    安装st-load时, 终端提示 “/var/run/yum.pid 已被锁定,PID 为 13908 的另一个程序正在运行.” 解决方法:直接在终端运行 rm -f /var/run/yum.pid ...

  7. Windows程序内部运行机制 转自http://www.cnblogs.com/zhili/p/WinMain.html

    一.引言 要想熟练掌握Windows应用程序的开发,首先需要理解Windows平台下程序运行的内部机制,然而在.NET平台下,创建一个Windows桌面程序,只需要简单地选择Windows窗体应用程序 ...

  8. Web程序的运行原理及流程(一)

    自己做Web程序的开发也有两年多了 从最开始跟风学框架  到第一用上框架的欣喜若狂 我相信每个程序员都是这样过来的 在大学学习一门语言 学会后往往很想做一个实际的项目出来  我当时第一次做WEB项目看 ...

  9. Linux nohup 程序后台运行

    &方式: Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台:          /usr/local/my ...

随机推荐

  1. 2020.3.14--训练联盟周赛 Preliminaries for Benelux Algorithm Programming Contest 2019

    1.A题 题意:给定第一行的值表示m列的最大值,第m行的值表示n行的最大值,问是否会行列冲突 思路:挺简单的,不过我在一开始理解题意上用了些时间,按我的理解是输入两组数组,找出每组最大数,若相等则输出 ...

  2. 使用Servlet前Tomcat介绍

    虚拟目录的映射方式:让tomcat服务器自动映射tomcat服务器会自动管理webapps目录下的所有web应用,并把它映射成虚似目录.换句话说,tomcat服务器webapps目录中的web应用,外 ...

  3. Noip模拟68 2021.10.4

    T1 玩水 成功在考试的时候注释掉正解,换成了暴力,只因为不敢保证正解思路的正确 脑子瓦特了,不知道把暴力打成函数拼在一起,不知道当时咋想的.... 就是你找有没有一个点上面和左面的字符一样, 如果这 ...

  4. Python课程笔记(十)

    不陌生,之前学习一个开源SpringBoot项目,Mysql5.5更换到5.7搞得头疼. 数据库连接的坑之前写的IDEA系列连接会遇到的问题.课程代码 今天上课就主要学习了python如何连接mysq ...

  5. IdentityServer4 负载均衡配置

    在不用到负载之前,一切都很好,但是部署多个实例之后,问题挺多的:session问题.令牌签发后的校验问题. 在此之前,先自查官方文档:Deployment - IdentityServer4 1.0. ...

  6. hdu 3863 No Gambling (不会证明,但是是对的,,)

    题意: N=4时 规则: 双方每次可以连接自己颜色的两个点(相邻,长度为1),线和线不能交叉重叠. 蓝方要连接左右,红方要连接上下. 蓝方先.问谁先连接? 思路: 经过观察....蓝方胜....... ...

  7. MarkDown学习随笔

    MarkDown语法的学习 标题 ​ 设置标题方法是在前面加#号,一级标题(最大)是加#+空格 ,二级标题是加##+空格,之后的以此类推. 字体 在文本的前后分别加上一个星号表示斜体字 在文本的前后分 ...

  8. hash 哈希表 缓存表

    系统初始hash表为空,当外部命令执行时,默认会从 PATH路径下寻找该命令,找到后会将这条命令的路径记录到 hash表中,当再次使用该命令时,shell解释器首先会查看hash 表,存在将执行之,如 ...

  9. 这些年我@yangbodong22011参与的开源

    2020年第一天,水一篇博客,对新年起码的尊重.这里记录下我参与的开源项目情况. Talk is cheap. Show me the code Linus Torvalds Jedis PR:htt ...

  10. Redis源码分析(dict)

    源码版本:redis-4.0.1 源码位置: dict.h:dictEntry.dictht.dict等数据结构定义. dict.c:创建.插入.查找等功能实现. 一.dict 简介 dict (di ...