作者 | 轩辕之风O

来源 | 编程宇宙技术

计算机如何执行你的代码?

知乎上有人提问:电脑怎样执行编程语言的?

很多刚刚入坑的小白可能对此完全没有概念,或者模模糊糊知道个大概,我们写下的一行行代码,计算机到底是如何在执行的呢?

我们以x86架构的CPU为研究对象,从一个例子出发,来尝试解答这个问题。

1

高级语言

为了方便编程,伟大的计算机先驱们发明了一个又一个的编程语言,使得我们可以用人类最容易理解的语法规则去告诉计算机完成我们想要的功能。

比如,一个C语言程序员写下了一行代码:

int sum = a + b;

一句简单的不能再简单的C语言语句。

但即便是如此简单,聪明绝顶的计算机却还是看不懂:这是弄啥捏?

这时候就需要一个翻译,负责把人类编写的高级语言“翻译”成计算机能看得懂的东西,这个翻译就是编译器。

2

编译链接

上面的高级语言语句经过编译器编译链接后,生成了一个目标运行平台为x86架构的可执行程序exe/elf,使用反编译工具IDA进行分析,可以看到这行代码编译后的样子是这样的:

mov eax, a    : 将变量a的值存入eax寄存器中

add eax, b    : 把变量b的值和eax寄存器的值相加,并将结果保存在eax寄存器中

mov sum, eax  : 将计算结果从eax寄存器写入sum变量

看到了吗,就像把大象关进冰箱需要分三步,计算机完成程序员的一条加法语句,也分了三步:取出被加数、加上加数、写入结果。

3

机器指令

上面的汇编指令只是为了人类理解方便的助记符,计算机同样也不认识这玩意,那几条指令在内存中实际上是这样的一串数据:

十六进制:

8B 45 EC 03 45 E0 89 45 F8

十六进制是为了书写方便,计算机真正能看到的只有二进制的比特流:

10001011 01000101 11101100 00000011 01000101 11100000 10001001 01000101 11111000

接下来,计算机要做的事情就是识别这些二进制流都是什么意思,转换成一条条的指令来执行。

在开始执行之前,先来了解一下指令格式。

4

指令格式

x86架构CPU指令集中的指令格式如下:

主要有六个部分:

  • [非必需] 指令前缀:我们经常用到的原子操作指令前面有一个lock前缀,就属于指令前缀。

  • [必需] 操作码:指令最核心的部分,标识这条指令是什么功能。

  • [非必需] ModR/M:内存/寄存器操作数字节

  • [非必需] SIB:索引寻址描述字节

  • [非必需] Displacement:常数偏移字节/半字/字

  • [非必需] Immediate:立即数字节/半字/字

需要注意的是,并不是每一条指令都包含上面的所有部分,许多指令只包含其中一部分字段。

根据操作码的长度不同,指令分为单字节操作码指令、双字节操作码指令、三字节操作码指令。

5

执行指令

计算机中真正负责指令执行的核心部件是中央处理器CPU,在CPU中有一个指令寄存器IP,全称是Instruction Pointer,在32位下,它叫EIP,在64位下它叫RIP

下面开始执行:

指令寄存器EIP指向了第一条指令,开始读取第一个字节:10001011,也就是0x8B。

开始指令译码,翻译出这是一条什么指令。

下面是x86架构的CPU指令操作码表:

CPU中的指令译码模块拿到手一看,呀,不是指令前缀,是个单字节操作码的mov指令,要往eax寄存器里面塞数据,数据从哪来呢?

再往后一看,0x45,再来译码:

好家伙,原来是根据ebp寄存器的值+一个8位的偏移来读取数据。

再往后读取一个字节,就是偏移值:EC。

现在第一条指令就译码出来了:将ebp+0xEC位置处的4个字节的数据取出来,放到eax寄存器中。这就是这一条指令要干的事情。

同时CPU还得出了另一个信息:这一条指令长度是3个字节,下一条指令的起始地址是在3个字节之后,随后,指令寄存器EIP向后拨动,指向下一条指令的地址:$+3。

指令译码完成之后,开始来正式执行它。

执行完一条以后,又来到指令寄存器EIP指向的地方,随后再次指令译码、执行,不断重复这个过程,依次执行每一条指令。

这其实就是CPU工作最基本的原理。

拓展

上面描述的过程是CPU在硬件电路层面完成的,但这种设计思想在软件领域也同样适用。

大家如果去研究Java虚拟机JVM和Python的解释器源代码时,也会发现有相似之处:JVM和解释器通过定义一套自己的“指令集”,然后它们的编译器使用这套指令集将Java和Python代码编译成对应的程序。

运行的时候也类似,虚拟机或者解释器不断识别每一条指令,译码、执行,和CPU执行指令的过程颇有几分相似。

C/C++语言编译的程序,最后是直接编译成了CPU的指令,所以跨平台能力差,如果换到ARM架构平台,原来的程序将无法执行,需要重新编译成新的平台的程序。

而Java、Python这类语言,是自己在软件层面的指令集,因为其自身已经开发了针对不同CPU平台的虚拟机、解释器,所以这些语言编写的程序移植性好,真正做到一次编写,到处运行。

总结

我们使用高级语言C、C++编写的程序代码,经过编译器的编译链接,最终变成CPU可以理解的机器指令,随后CPU在执行时通过不断的译码、执行,最终实现高级语言所描述的功能。

现在你知道你用编程语言写下的程序是如何跑起来的了吗?

往期推荐

Docker Desktop 向大公司宣告收费

双非院校的计算机毕业生能进大厂吗?

谁说理工男不浪漫?吸猫日常

被 AI 算法“监控”的打工人

点分享

点收藏

点点赞

点在看

一行代码,揭开 CPU 执行原理!相关推荐

  1. 一行代码揭开CPU执行原理

    参考:一行代码,揭开CPU执行原理! 作者:嵌入式ARM 网址:https://mp.weixin.qq.com/s/qFnKhWqBGRCFAnp_KC1dmw 目录 1.高级语言 2.编译链接 3 ...

  2. 一行代码,揭开CPU执行原理!

    计算机如何执行你写的代码? 知乎上有人提问:电脑怎样执行编程语言的? 很多刚刚入坑的小白可能对此完全没有概念,或者模模糊糊知道个大概,我们写下的一行行代码,计算机到底是如何在执行的呢? 我们以x86架 ...

  3. Rosserial Arduino Library中从一行代码开始探究系统原理

    Rosserial Arduino Library中从一行代码开始探究系统原理 俗话说,管中窥豹,可见一斑. 从一行代码开始,分析rosserial arduino库的脉络.走码观花,到哪儿是哪儿. ...

  4. 更改计算机属性里的cpu名称,一行代码修改CPU的个性化显示名称,

    一行代码修改CPU的个性化显示名称, 2020-10-01 14:06:40 55点赞 334收藏 52评论 追加修改(2020-10-04 21:39:32): 代码修改 REG ADD " ...

  5. C语言的实现经过(C代码到CPU执行)

    2018-01-05 创建人:Ruo_Xiao 2018-01-06 修改人:Ruo_Xiao 1.添加编辑器之后,预处理之前的编译器的操作. 2.添加对优化器的简单的说明. 2018-01-12 修 ...

  6. octobercms 执行php代码_PHP7语言执行原理

    常用的高级语言有很多种,根据运行的方式不同,大体分为两种:编译型语言和解释型语言. 编译是指在应用源程序执行之前,就将程序源代码"翻译"成汇编语言,然后进一步根据软硬件环境编译成目 ...

  7. REC代码及命令执行漏洞

    RCE代码及命令执行漏洞 1.RCE介绍 全称:remote command/code execute 分为远程命令执行和远程代码执行 1.命令执行漏洞: 直接调用操作系统命令 代码执行漏洞: 靠执行 ...

  8. 神奇的Python-实现曼德布洛特(Mandelbrot)集合(一行代码,matplotlib numpy,tensorflow)分别实现

    神奇的Python-实现曼德布洛特(Mandelbrot)集合(一行代码,matplotlib numpy,tensorflow)分别实现 Mandelbrot图实际上是由Mandelbrot集合构成 ...

  9. idea2020shezhi代码检查级别_结合 CPU 理解一行 Java 代码是怎么执行的

    根据冯·诺依曼思想,计算机采用二进制作为数制基础,必须包含:运算器.控制器.存储设备,以及输入输出设备,如下图所示. 我们先来分析 CPU 的工作原理,现代 CPU 芯片中大都集成了,控制单元,运算单 ...

最新文章

  1. 基于YOLO的密集人脸检测(课程设计)
  2. Linux C 程序的开发环境
  3. SVN服务器与客户端的配置
  4. 遍历文件夹_使用JavaScript遍历本地文件夹的文件
  5. java.lang.IllegalStateException: getOutputStream() has already been called for this response
  6. MangoFix:iOS热修复另辟蹊径
  7. 为什么python删除不了_为什么python的imp.reload()不会删除旧的类和函数?
  8. m不能被3整除c语言表达式,求mn-之间所有不能被3整除的整数之和求 – 手机爱问...
  9. 16名本科生领衔的芯片公司 芯微电子要上市了?
  10. android 高仿随便走,随便走下载_随便走APP手机最新版安装 - 风云下载
  11. Oracle执行计划稳固
  12. c++右值引用以及使用
  13. App测试中ios和Android的区别1
  14. localhost和127.0.0.1有什么区别?(转载)
  15. linux下MySQL密码修改过程记录
  16. opera价格设置(一)
  17. 360se html怎么删除,删除360浏览器的方法 如何删除360浏览器?
  18. html5css字竖着显示,css如何设置竖排文字?
  19. [转]Xmanager连接Linux远程桌面(后面添加了自己的部分)
  20. C++/C语言-基本语法

热门文章

  1. java 格式化字符串_Java入门 - 语言基础 - 14.String类
  2. 计算机操作系统同步互斥
  3. 刷卡提示57能恢复吗_硬盘格式化之后数据还能恢复吗?
  4. 苹果自带相册打马赛克_如果你用苹果手机!学会这3个技巧,就能让手机变得更加好用...
  5. python常用包数据分析_数据分析领域常用的五个Python包
  6. 双胞胎一个上北大一个上清华,秘诀6个字!还有女生收到清华通知书说“考砸了”……...
  7. 北京大学:“巍巍上庠 国运所系”北大为时代发展而歌(附历年高考各省投档线)...
  8. 他,先后担任4所大学校长!
  9. 继北大“鸿hao之志”后,清华出现“热列欢迎”…
  10. go tcp连接_TCP漫谈之keepalive和time_wait