计算机系统->Hello World的一生 | 程序如何运行
2021年11月27日准备发在基地微信公众号上的推文。
综合了多篇大佬的博客,以及自己已经知道的知识,对一些疑惑进行了现阶段我认为还算满意的解答。
不过又产生了很多疑问:
- 内存和磁盘的关系
- CPU是如何运行机器指令的(虽然大概想过去会是数字逻辑上的电路的组合)
- ......
========================================================================================================================================
我写的上一篇推文是: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 复习
- 程序从按下“编译”到装入内存需要哪些过程?
- GCC工具链有哪些?
计算机系统->Hello World的一生 | 程序如何运行的更多相关文章
- C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper
前言 在开发应用程序时,通常只让程序运行一个实例.所以,就要判断程序是否已经运行. 下面是我自己在项目中使用到,封装好的帮助类.有 普通的 C# 应用程序 和 Windows CE 和 Windows ...
- C# Winform防止一个程序重复运行
1: //在写一些服务型的软件的时候,你可能不希望一个操作系统里有两个副本在运行,这样也许会扰乱你的操作.这时,你就需要限制程序的副本.下面的这个方法,很简单的就可以实现上述功能. using Sys ...
- 关于SQL Server 安装程序在运行 Windows Installer 文件时遇到错误
前几日安装sql server2008r2 的时候碰到这个问题: 出现以下错误: SQL Server 安装程序在运行 Windows Installer 文件时遇到错误. Windows Insta ...
- <<< php程序在运行后报“internal server error”错误
上传的php程序在运行后报“internal server error”错误,检查以下两方面: 1.请您检查php程序的属性是否设置为755,如果php程序的属性不是755,那么运行的时候会报“int ...
- 如何利用 JConsole观察分析Java程序的运行,进行排错调优
原文链接:http://jiajun.iteye.com/blog/810150 一.JConsole是什么 从Java 5开始 引入了 JConsole.JConsole 是一个内置 Java 性能 ...
- /var/run/yum.pid 已被锁定,PID 为 XXXX 的另一个程序正在运行。
安装st-load时, 终端提示 “/var/run/yum.pid 已被锁定,PID 为 13908 的另一个程序正在运行.” 解决方法:直接在终端运行 rm -f /var/run/yum.pid ...
- Windows程序内部运行机制 转自http://www.cnblogs.com/zhili/p/WinMain.html
一.引言 要想熟练掌握Windows应用程序的开发,首先需要理解Windows平台下程序运行的内部机制,然而在.NET平台下,创建一个Windows桌面程序,只需要简单地选择Windows窗体应用程序 ...
- Web程序的运行原理及流程(一)
自己做Web程序的开发也有两年多了 从最开始跟风学框架 到第一用上框架的欣喜若狂 我相信每个程序员都是这样过来的 在大学学习一门语言 学会后往往很想做一个实际的项目出来 我当时第一次做WEB项目看 ...
- Linux nohup 程序后台运行
&方式: Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台: /usr/local/my ...
随机推荐
- python单例模式设计
class MyTest(): my_obj = None def __new__(cls,*args,**kwargs): if not cls.my_obj: cls.my_obj =object ...
- Java(46)类加载器
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201673.html 博客主页:https://www.cnblogs.com/testero ...
- suricata的模块和插槽
参考资料 suricata官方文档https://suricata.readthedocs.io/en/latest/performance/runmodes.html#different-runmo ...
- DL4J实战之六:图形化展示训练过程
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<DL4J实战>系列的第六 ...
- [技术博客]使用pylint实现django项目的代码风格检查
使用pylint实现django项目的代码风格检查 前言 一个项目大多都是由一个团队来完成,如果没有统一的代码规范,那么每个人的代码的风格必定会有很大的差别.且不说会存在多个人同时开发同一模块的情 ...
- OO_JAVA_电梯运行模拟_单元总结
电梯运行模拟--三次作业总结 目录 电梯运行模拟--三次作业总结 总体遵循的设计思路 逻辑解耦 电梯与调度器解耦 楼层信息的存储和变更与电梯.调度器解耦 调度器运行流程解耦 第一次电梯,蠢笨串行先到先 ...
- allegro查看线宽的方法
- VMware Workstation 16.2 Pro for Linux SLIC 2.6 & Unlocker
请访问原文链接:https://sysin.org/blog/vmware-workstation-16-linux-slic/,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin. ...
- hdu 1503 Advanced Fruits(DP)
题意: 将两个英文单词进行合并.[最长公共子串只要保留一份] 输出合并后的英文单词. 思路: 求最长公共子串. 记录路径: mark[i][j]=-1:从mark[i-1][j]转移而来. mark[ ...
- cf 11A Increasing Sequence(水,)
题意: A sequence a0, a1, ..., at - 1 is called increasing if ai - 1 < ai for each i: 0 < i < ...