探索CPU的黑盒子:解密指令执行的秘密
引言
在我们之前的章节中,我们着重讲解了CPU内部的处理过程,以及与之密切相关的数据总线知识。在这个基础上,我们今天将继续深入探讨CPU执行指令的相关知识,这对于我们理解计算机的工作原理至关重要。
CPU 是一系列寄存器的集合体
我们以使用的 Intel CPU 为例,其中包含数百亿个晶体管。在逻辑上,我们可以认为 CPU 实际上由一组寄存器组成。寄存器是 CPU 内部的简单电路,由多个触发器(Flip-Flop)或锁存器(Latches)组成。
触发器和锁存器实际上是由不同原理的数字电路组成的逻辑门。
一个 CPU 中包含许多不同功能的寄存器,我将介绍其中三种比较特殊的寄存器。
首先是 PC 寄存器(Program Counter Register),也称为指令地址寄存器(Instruction Address Register)。顾名思义,它用于存储下一条需要执行的计算机指令的内存地址。
第二个是指令寄存器(Instruction Register),用于存储当前正在执行的指令。
第三个是条件码寄存器(Status Register),其中的标志位(Flag)存储了 CPU 进行算术或逻辑计算的结果。
除了这些特殊的寄存器,CPU 还包含更多用于存储数据和内存地址的寄存器。通常每类寄存器不止一个,我们根据存储的数据内容给它们命名,比如整数寄存器、浮点数寄存器、向量寄存器和地址寄存器等。有些寄存器既可以存储数据,又可以存储地址,我们称之为通用寄存器。

程序计数器
程序计数器(Program Counter,简称PC)是用来存储下一条指令所在单元的地址的寄存器。在程序执行时,PC的初始值被设置为程序第一条指令的地址。当顺序执行程序时,控制器首先从内存中取出一条指令,该指令的地址由PC指示。然后,控制器分析和执行该指令,并将PC的值加1,指向下一条要执行的指令的地址。
让我们以一个相加操作的例子来详细解释程序计数器的执行过程。假设我们有一段程序,其目的是将数字123和456相加,并将结果输出到显示器上。

程序在启动时,经过编译和解析后,会被操作系统从硬盘复制到内存中。假设程序的起始位置是地址0100。操作系统会将程序计数器设置为0100作为起始位置,并开始执行程序。每执行一条指令后,程序计数器的值会增加1,或者直接指向下一条指令的地址。CPU根据程序计数器的值,从内存中读取指令并执行。换句话说,程序计数器控制着程序的执行流程。
而在Java虚拟机(JVM)中,程序计数器是一种虚拟机级别的数据结构,用于存储当前线程正在执行的JVM指令的地址或索引。它是线程私有的,每个线程都有自己独立的程序计数器。
程序计数器在Java虚拟机中的作用与在计算机体系结构中的作用类似,即控制程序执行流程。它会指示下一条要执行的指令,以便JVM能够顺序地执行程序。
区别在于,计算机体系结构中的程序计数器是硬件级别的寄存器,而Java虚拟机中的程序计数器是虚拟机级别的数据结构。
条件分支和循环机制
高级语言中的条件控制流程主要分为三种:顺序执行、条件分支和循环判断。顺序执行是按照地址的内容顺序执行指令。条件分支是根据条件执行任意地址的指令。循环是重复执行同一地址的指令。就跟Java中使用的判断类似。
顺序执行的情况比较简单,每执行一条指令程序计数器的值就是当前地址加一。
在程序中,条件分支语句可以使程序计数器的值指向任意的地址。这样一来,程序就可以返回到上一个地址,以便重复执行同一个指令,或者跳转到任意指令。下面以条件分支为例来详细说明程序的执行过程(循环也具有类似的原理和过程):

条件和循环分支会利用跳转指令(jump)来实现。程序的执行过程和顺序流程是相同的。CPU从地址0100开始执行指令。在地址0100和0101处的指令是按顺序执行的,程序计数器(PC)的值递增。当执行到地址0102处的指令时,会判断寄存器0106的数值是否大于0。如果满足条件,则会跳转(jump)到地址0104处的指令,将数值输出到显示器中,然后程序结束。这意味着地址0103处的指令被跳过了。这与我们在程序中使用if()条件判断的原理是相同的。在不满足条件的情况下,指令会直接跳过。因此,程序计数器的执行过程不是简单地递增1,而是跳转到下一条指令的地址。
函数调用机制
接下来,我们将继续介绍函数调用机制。即使是使用高级语言编写的程序,函数调用的处理也是通过将程序计数器的值设置为函数的存储地址来实现的。在函数执行跳转指令之后,必须进行返回处理,否则仅仅进行指令跳转是没有意义的。下面是一个实现函数跳转的示例:

函数调用和返回是非常重要的两个指令,它们分别是call和return指令。在将函数的入口地址设置到程序计数器之前,call指令会将调用函数后要执行的指令地址存储在名为栈的主存中。函数处理完毕后,通过函数的出口执行return指令。return指令的功能是将保存在栈中的地址设置到程序计数器。
例如,当调用MyFun函数之前,地址0154被保存在栈中。在MyFun函数处理完成后,将会将0154的地址保存在程序计数器中。这样,程序就可以正确地返回到调用MyFun函数的地方继续执行后续的指令。函数调用和返回的机制确保了程序的流程能够正确地跳转和返回,使得程序的执行能够按照预期的顺序进行。
CPU 指令执行过程
冯·诺伊曼型计算机的CPU工作可以分为五个阶段:取指令、指令译码、执行指令、访存取数、结果写回。
在取指令阶段,CPU从内存中读取指令,并将下一条指令的地址存储在程序寄存器中。这个阶段主要涉及的是内存的读取操作,以获取下一条指令的地址。
指令译码阶段紧随其后,指令译码器根据指令的格式将其拆分和解释,识别指令的类型和操作数的获取方法。这个阶段的目的是将指令翻译成可执行的操作,为执行指令阶段做准备。
执行指令阶段是CPU执行指令的主要阶段。在这个阶段,CPU根据指令的要求完成各种操作,实现指令的功能。这可能涉及到算术运算、逻辑运算、数据传输等操作,具体取决于指令的类型。
访存取数阶段是在执行指令阶段之后进行的。根据指令的需求,可能需要从内存中获取数据。这个阶段的任务是根据指令的地址码找到操作数在主存中的地址,并从主存中读取该操作数用于运算。这个阶段与访问主存相关,确保指令所需的数据可供使用。
结果写回阶段是最后一个阶段,将执行指令阶段的运算结果数据写回到某种存储形式。通常情况下,结果数据被写入CPU的内部寄存器中,以便后续指令快速访问。这个阶段的目的是将计算得到的结果保存下来,供其他指令使用或输出。
这五个阶段的顺序保证了CPU的正常运行,并且每个阶段都有其特定的任务,以实现指令的正确执行和数据的处理。通过优化这些阶段的执行过程,可以提高计算机的性能和效率。
总结
在本章中,我们继续深入探讨了CPU如何执行指令的相关知识。首先,我们了解了CPU是由一系列寄存器组成的,包括PC寄存器、指令寄存器和条件码寄存器等。然后,我们讨论了程序计数器的作用,它控制着程序的执行流程,并且在条件分支和循环中起到关键作用。接着,我们介绍了函数调用机制,包括call和return指令的使用,以及如何正确地跳转和返回。最后,我们了解了CPU指令执行过程的五个阶段:取指令、指令译码、执行指令、访存取数和结果写回。通过优化这些阶段的执行过程,可以提高计算机的性能和效率。通过本章的学习,我们对CPU如何执行指令有了更深入的了解,进一步加深了对计算机工作原理的理解。
探索CPU的黑盒子:解密指令执行的秘密的更多相关文章
- [No0000167]CPU内部组成结构及指令执行过程
计算机的基本硬件系统由运算器.控制器.存储器和输入.输出设备五大部件组成.运算器和控制器等部件被集成在一起统称为中央处理单元(Central Processing Unit,CPU). CPU的功能 ...
- CPU结构与指令执行过程简介
CPU(Central Processing Unit)是计算机中进行算术和逻辑计算处理指令的主要部件. CPU结构 CPU由通用寄存器组,运算器,控制器和数据通路等部件组成. 寄存器包括 数据寄存器 ...
- 【基础知识】CPU 指令执行的五个阶段,cpu就是用来执行指令的
IF(Instruction fetch) 取指:从 Instruction-Memory 中读取指令,并在下一个时钟上升沿到来时把指令送到 ID 级的指令缓冲器 id_ir 中.该级控制信号决定下一 ...
- Linq指令执行分析
Linq指令执行分析 一.Linq中IEnumerable的结构 Linq在执行聚合操作和ToXxx系统方法之前,一直都是一个数据源和一串指令(下面的讨论都是基于未执行聚合操作和ToXxx系统方法之前 ...
- Linux进程启动/指令执行方式研究
1. 通过glibc api执行系统指令 0x1:system() glibc api system是linux系统提供的函数调用之一,glibc也提供了对应的封装api. system函数的原型为: ...
- CPU 是如何认识和执行代码的
CPU的介绍 CPU 也称为微处理器,是计算机的心脏和/或大脑. 深入研究计算机的核心,可以帮助我们有效地编写计算机程序. CPU 是计算机的心脏和大脑,它执行提供给他们的指令.它的主要工作是执行算术 ...
- angularJs指令执行的机制==大概的三个阶段
第一阶段:加载阶段 angularJs要运行的话,需要去等待angular.js加载完成,加载完之后呢,angular就会去查找到ng-app这个指令,ng-app在每个应用里面只能出现一次, 它也就 ...
- 从虚拟机指令执行的角度分析JAVA中多态的实现原理
从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...
- 如何使用java指令执行含package的class文件
代码文件存放在E:/Temp/JAVA_TEMP/tmp文件夹,代码如下: package tmp; public class Temp { public static void main(Strin ...
- 操作系统实战45讲笔记- 05 CPU工作模式:程序执行的三种模式
实模式 实模式又称实地址模式,实,即真实,这个真实分为两个方面,一个方面是运行真实的指令,对指令的动作不作区分,直接执行指令的真实功能,另一方面是发往内存的地址是真实的,对任何地址不加限制地发往内存. ...
随机推荐
- Matlab学习1
Matlab 数据类型 数字 字符和字符串 矩阵 元胞数组 结构体 清空环境变量及命令 cls % 清除Command Windows中的所有命令 clear all % 清除Workspace*中的 ...
- AWVS——自动化检测发现漏洞
AWVS简介 *AWVS作为一个工具,不可能把所有漏洞扫描出来,仅仅是作为一个渗透网站时的辅助工具 自动化Web漏洞扫描工具(基于漏洞匹配方法,通过网络爬虫测试网站安全) AWVS通过SQL注入攻击. ...
- 数据安全没保证?GaussDB(for Redis)为你保驾护航
摘要:GaussDB (for Redis)通过账号管理.权限隔离.高危命令禁删/重命名.安全IP免密登录.实例回收站等企业级特性,保障用户数据库数据和信息安全. 本文分享自华为云社区<数据安全 ...
- 2023年icpc大学生程序设计竞赛-crf
第一次在除郑轻以外的校外的地方比赛,也是第一次出市比赛,赛程也比较长.20号出发的时候遇到一些意外,不过无伤大雅,第一天热身赛平平无奇,晚上的时候补了一下前年icpc的题,一个多小时做了五题,很是自信 ...
- Semantic Kernel Java SDK,为Java应用程序提供AI功能集成
美国时间 2023 年 7 月 19 日,Semantic Kernel 团队在其官方博客[1]上宣布发布 Java 版Semantic Kernel. Samantic Kernel系列的源代码可在 ...
- STA学习笔记-0
如今的逻辑设计复杂度和工作频率要求越来越高.为了保证设计稳定可靠,必须对设计附加时序约束,对综合实现结果进行时序分析. 导言 时序约束:主要用于规范设计的时序行为,表达设计者期望满足的时序条件,指导综 ...
- Swiper.vue?56a2:132 Uncaught DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
错误代码 解决方案 删除div标签.修改后,如下所示:
- CVE-2021-3156 Linux sudo权限提升漏洞复现
前言: 现在最火的莫不过是这个linux sudo权限提升漏洞了,sudo命令可以说是在linux中十分出名的命令了,在运维时很多时候都需要用到sudo命令,通过此漏洞,可以对具有一定权限的普通用户, ...
- Prototype 原型模式简介与 C# 示例【创建型4】【设计模式来了_4】
〇.简介 1.什么是原型模式? 一句话解释: 针对比较耗时的对象创建过程,通过原型的 Clone 方法来克隆对象,而非重新创建. 原型设计模式(Prototype Design Pattern)是 ...
- 【故障公告】多年的故障老朋友又来了:数据库服务器 CPU 100%
数据库服务器 CPU 100% 问题几乎每年都要来几次,从来都不事先打一声招呼,今年的第2次在我们正忙着会员救园的时候来了. 今天 13:35 首先收到我们自己的异常告警通知: Execution T ...