智安网络丨一行代码,揭开CPU执行原理!

2023-05-16

计算机如何执行你写的代码?
知乎上有人提问:电脑怎样执行编程语言的?

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

我们以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在执行时通过不断的译码、执行,最终实现高级语言所描述的功能。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

智安网络丨一行代码,揭开CPU执行原理! 的相关文章

  • 如何为Python 3子进程分配CPU亲和力?

    我在 Python 方面还是个新手 我在 Windows 7 和 Windows 10 上运行 Tkinter GUI 我有一个子进程以 1 KHz 运行数据记录器例程 我想为子进程设置 cpu 亲和力 我正在使用 Python 3 8 进
  • 在 C++ 中处理 CPU 异常

    是否有跨平台的方法来处理 CPU 异常 例如分段错误或除以零 可以说 我需要调用一些潜在不安全的函数 例如从插件文件 这可能会导致段错误 或在执行之前无法测试的一些其他问题 我知道 C 标准库有信号处理函数 但我不知道如何使用它们来处理问题
  • 上下文切换线程等待

    我已经寻找这个问题的答案一天了 但找不到直接的答案 我正在阅读上下文切换等待队列之类的内容 确实很好地掌握了所有内容 在阅读一篇文章时 写到当发生车队情况时 将会有大量的上下文切换 那么让我直接说一下 假设一个线程处于等待互斥体解锁的队列中
  • 获取CPU温度

    我想知道CPU的温度 以下是我使用 C 和 WMI 所做的工作 我正在读取 MSAcpi ThermalZoneTemperature 但它始终相同 而且根本不是 CPU 温度 有没有办法不用写驱动就能获取CPU的真实温度 或者有什么我可以
  • Python CPU 计数在一台 Windows 服务器上工作但在另一台服务器上不起作用?

    我编写的代码可以在 Windows XP 和 Windows Server 2008 64 位上运行 但是 我刚刚启动了 Amazon Windows 64 位实例 代码失败 非常简单 看起来像这样 import multiprocessi
  • Android Studio 和 Ryzen CPU?

    我知道它可能会被标记为重复 但没有一个线程对我有帮助 所以我决定自己做一个 I m a Java后端开发人员我决定学习一些 Android 的东西 几年前我在 Android Studio 工作过i5 4570处理器 然后我放弃了 现在我发
  • XNA 的 CPU 使用率高

    我今天刚刚注意到 当我编译并运行一款新的 XNA 4 0 游戏时 其中一个 CPU 线程以 100 的速度运行 并且帧速率下降到 54 FPS 奇怪的是 有时它可以在 60 FPS 下运行 但随后就会下降到 54 FPS 我以前没有注意到这
  • 尝试在 Windows PC 上禁用处理器空闲状态(C 状态)

    我需要防止处理器进入空闲状态 非C0 C状态 诚然 我对处理器 C 和 P 状态了解不多 所以请耐心等待 我们使用来自第三方供应商的相机 该相机偶尔会提供损坏的帧 供应商已确定 当 CPU 进入空闲状态时 它会干扰通过火线传输帧 为了确认这
  • 使CPU的缓存失效

    当我的程序执行具有获取语义的加载操作 具有释放语义的存储操作或可能是完整栅栏时 它会使 CPU 的缓存无效 我的问题是 缓存的哪一部分实际上失效了 只有保存我使用的获取 释放变量的缓存行 或者整个缓存都失效了 L1 L2 L3 等等 当我使
  • 如何使用C获取Linux中的CPU数量?

    Linux 中是否有 API 可以获取可用 CPU 的数量 我的意思是 不使用 proc cpuinfo 或任何其他系统节点文件 我使用 sched h 找到了这个实现 int GetCPUCount cpu set t cs CPU ZE
  • 如何使用 bash 命令创建 CPU 峰值

    我想在 Linux 机器上创建接近 100 的负载 它是四核系统 我希望所有核心都全速运行 理想情况下 CPU 负载将持续指定的时间 然后停止 我希望 bash 有一些技巧 我在想某种无限循环 I use stress http linux
  • Django 开发服务器 CPU 密集型 - 如何分析?

    我注意到本地 windows7 机器上的 django 开发服务器 版本 1 1 1 正在使用大量 CPU 根据任务管理器的 python exe 条目 约为 30 即使处于空闲状态 即没有请求到来进 出 是否有一种既定的方法来分析可能造成
  • Linux:如何对系统内存施加负载?

    我正在开发一个小功能 它可以让我的用户了解 CPU 的占用情况 我在用着cat proc loadavg 它返回众所周知的 3 个数字 我的问题是 当我正在开发时 CPU 目前没有做任何事情 有没有一种好方法可以在CPU上产生一些负载 我在
  • 通过 C 将线程固定到 cpuset 中的核心

    我有 cgroup cpuset set1 set1有2 5 8 我想将一个进程绑定到该 cpuset 然后将该进程中的一个线程固定到核心 4 cpuset 的名称 线程名称以及我应该将线程绑定到的核心位于 m 配置文件中 是否有任何 C
  • C++ 中的 CPUID 实现

    我想知道这里是否有人有一些可以从任何托管 net 语言引用的 C CPUID 实现的好示例 另外 如果情况并非如此 我是否应该注意 X86 和 X64 之间的某些实现差异 我想使用 CPUID 来获取运行我的软件的机器上的信息 崩溃报告等
  • 普通的 x86 或 AMD PC 是直接从 ROM 运行启动/BIOS 代码,还是先将其复制到 RAM? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我知道现代计算机已经修改了哈佛架构 它们可以从保存数据的地方以外的地方读取指令 这一事实是否允许它们直接从 ROM 芯片获取指令 他们是先
  • NodeJS CPU 一次飙升至 100%

    我有一个用 NodeJS 编写的 SOCKS5 代理服务器 我正在使用原生net and dgram打开 TCP 和 UDP 套接字的库 它可以正常工作大约 2 天 所有 CPU 的最大利用率约为 30 两天没有重新启动后 一个 CPU 峰
  • 测量进程消耗的 CPU 时钟

    我用 C 语言编写了一个程序 它是作为研究结果创建的程序 我想计算程序消耗的确切 CPU 周期 精确的循环次数 知道我怎样才能找到它吗 The valgrind tool cachegrind valgrind tool cachegrin
  • 为什么将多线程应用程序限制在一个核心上会使其运行速度更快?

    我有一个本机多线程Win32用 C 编写的应用程序 大约有 3 个相对繁忙的线程和 4 到 6 个不执行太多操作的线程 当它在正常模式下运行时 在 8 核计算机上 总 CPU 使用率总计约为 15 并且应用程序在大约 30 秒内完成 当我通
  • Nodejs 异步函数是否使用所有 CPU 核心?

    如果我使用异步函数或带有回调的函数 例如本机 fs 模块 http 等 它们会默认在所有 cpu 核心上运行吗 或者整个系统只使用 1 个核心 Node js 中的一些异步操作 例如文件 I O fsmodule 将通过 libuv 中的线

随机推荐

  • IOS TableView Cell重用机制及TableView常用Code

    写的太好了 xff0c 多谢楼主的无私分享 文章来自 xff1a http heidianfeng blog 163 com blog static 6184345620121114104552518 创建UITableViewContro
  • 编译Linux驱动程序

    基于Ubuntu 12 10 xff0c 编译Linux驱动程序 1 准备linux内核源码 此时 xff0c 我要编译的驱动是基于Ubuntu 12 10内核的 xff0c 所以我下载的是其对应的内核源码包 xff1a linux 3 5
  • 卸载windows10子系统卸载linux

    参考地址 xff1a https docs microsoft com en us windows wsl wsl config 查看所有已经安装的分发版本 xff1a wsl list all 查看正在运行的分发版本 xff1a wsl
  • github镜像站

    github镜像站 xff1a https hub fastgit org GitHub 在国内经常会出现无法访问的情况 xff0c 下面分享几个 GitHub 镜像站供大家使用 xff01 全局加速 可直接访问站点 xff0c 查看代码等
  • vnc连接linux失败,vnc连接linux失败解决办法

    在日常工作学习中 xff0c 经常会使用到vnc连接 xff0c 那有小伙伴知道如何进行vnc连接linux吗 xff1f 当vnc连接linux失败又该如何解决呢 xff1f 之前有简单介绍过如何实现vnc连接linux 那接下来让我们一
  • 域名是如何关联到CDN的

    用户在访问一个域名的时候 xff0c 网络中是怎么知道这个域名到底是配置在哪一个CDN厂商的呢 xff1f 笔者以test1 huiziguoxueshe com为例 xff0c 来描述下具体的过程 xff0c 如下所示 xff1a ste
  • 第五章:软件详细设计

    真是应了那句 xff1a 白天游四方 晚上点灯补裤裆 捂脸 xff09 xff0c 孩子睡了夜深人静了 我才是开始我的小笔记整理工作 详细设计是软件设计的第二阶段 xff0c 这一阶段的工作 xff0c 就是要对系统中的每个模块给出足够详细
  • 第7章 软件测试(1)

    今天是个开心的日子 xff0c 具体为啥开心我知道你懂得 继续我的龟速学习小笔记 它来了它来了 xff0c 你说它很简单 xff0c 当我看到此章的一部分内容后发现了原来学霸和学渣差别就是如此大 xff08 捂脸 xff09 xff0c 今
  • 第7章 软件测试(3)

    一晃3天没有学习了 xff0c 昨天的阅读量创立了一个新高 xff0c 内心还是很欢喜的 7 4 2黑盒技术 黑盒技术着重测试软件功能 xff0c 需重点研究需求说明和总体设计中有关程序功能输入 输出之间的关系等信息 xff0c 从而与测试
  • 第七章 软件测试(此章完结)

    春乏秋困 xff0c 一个早上哈气连天 脖子酸 腰痛 xff08 捂脸 xff09 近期叫醒我的不是闹钟也不是梦想 xff0c 而是凌晨4点和6点广播大喇叭喊居民做核酸的声音 xff0c 还是别的小区的 xff08 再次捂脸 xff09 也
  • 第十章:面向对象分析(2)

    3 泛化关系 泛化关系和类找那个的泛化概念是一样的 xff0c 于用例继承父用例的行为和含义 xff0c 还可以增加或覆盖父用例的行为 xff0c 子用例可以出现在任何父用例出现的位置 xff08 父和子均有具体的实例 xff09 也可以重
  • 第十章:面向对象分析(此章完结)

    10 4 4建立活动图 活动具体表现为由一系列动作组成的执行过程 xff0c 将各种活动及不同活动之间的转换 xff0c 用图形进行表示就构成了活动图 xff0c 作用是对系统的行为建模 1 活动图与流程图 活动图描述系统使用的活动 xff
  • 第十五章 软件工程新技术

    俺家老大说这一章我不需要仔细看 xff0c 快快过一遍就行 xff08 可能是觉得以我的能力一时半会也用不到吧 xff08 捂脸 xff09 xff09 那么我就抄一段本章小结吧 xff0c 后面如有需要我在重新认真学习 xff08 奸笑
  • 第四章 软件测试方法(2)

    上周学习了白盒 xff0c 本周开始学习黑盒测试 4 3黑盒测试 黑盒测试 xff08 Black Box Testing xff09 也称功能测试 xff0c 主要测试每个功能是否正常使用 是软件测试使用中最广泛的一类测试 在黑盒测试中
  • vnc viewer手机中文版,超好用的5款vnc viewer手机中文版

    在平时工作中 xff0c 经常会用到vnc viewer软件 当软件打开都是英文介绍 xff0c 真的让人很头痛 在各种各样的vnc viewer手机中文版软件中 xff0c 要想找到那款让你使用方便的软件 xff0c 真的很不容易 xff
  • 第九章 APP项目测试(4) 测试工具

    接上面一篇 继续 xff08 7 xff09 kill process after error 参数说明 xff1a 用于指定当应用程序发生错误时 xff0c 是否停止运行 如果指定此参数 xff0c 当应用程序发生错误时 xff0c 应用
  • 第九章 APP项目测试(此章完结)

    9 4 5 Fiddler 是一个HTTP的调试代理工具 xff0c 它以代码服务器的方式 xff0c 监听系统的HTTP网络数据 xff0c 俗称抓包工具 可直接去官网下载安装 1 Fiddler工具介绍 启动Fiddler后 xff0c
  • 软硬件基础知识学习--小日记(1)

    终于看完了软件工程和软件测试技术指南两本书 xff0c 因为是自学总觉得前学后忘 有时候找老公不耻下问 xff0c 他总是很完美的把我问的哑口无言 昨天意外翻到黑马程序的的视频 xff0c 觉得非常适合我这0基础的小白 然后就有了今天的小日
  • Qt for Windows版本下编译QtDBus模块

    转载时请注明出处和作者联系方式 作者联系方 式 xff1a Lutx lt 80437 at zj dot com gt Qt中已经包含了QtDBus模块 但此模块只能在Unix系统下使用 却不支持Windows系统 这里介绍的是Windo
  • 智安网络丨一行代码,揭开CPU执行原理!

    计算机如何执行你写的代码 xff1f 知乎上有人提问 xff1a 电脑怎样执行编程语言的 xff1f 图片 很多刚刚入坑的小白可能对此完全没有概念 xff0c 或者模模糊糊知道个大概 xff0c 我们写下的一行行代码 xff0c 计算机到底