指令集 与 cpu

摘要:
指令集系统不存储在cpu中,它集成在操作系统内核底部的hal中,属于操作系统和硬件之间的接口。这就像计算一个复杂的数学问题。无论问题有多复杂,解决问题的每一步都必须遵循最基本的定理公式,而指令集就是计算机解决问题所需的定理公式。指令集系统的统一解决了

http://cache.baiducontent.com/c?m=9d78d513d9d437ab4f9d9e697c15c0116e4381132ba7a1020ca08448e2732d405016e3ac57530770a4d13b275fa0131aacb22173441e3df2de8d9f4aaaf3c87375cf3034074ddb1e0f905ef88a007e9c7c8d5aebaa12e6b8f138&p=ce6f8315d9c342a817b4c7710f0c8d&newp=9c759a45d5c452f60be29638130097231610db2151ddd701298ffe0cc4241a1a1a3aecbf26281b04d0c4766106ac495fe1f03171370034f1f689df08d2ecce7e3cd1&user=baidu&fm=sc&query=%D6%B8%C1%EE%BC%AF+%D3%B2%BC%FE&qid=a93be8c30006c2c5&p1=2

(已更正) 这个问题包括CPU的硬件结构和汇编语言的范畴. 这里梳理一下.

首先, 题主"李建国"自问自答的部分说的是正确的, CPU的指令集是软件与CPU这两个层级之间的接口, 而CPU自己, 就是对于这一套CPU指令集的"实例化"

无论处于上层的软件多么的高级, 想要在CPU执行, 就必须被翻译成"机器码", 翻译这个工作由编译器来执行. 编译器在这个过程中, 要经过"编译", "汇编", "链接"几个步骤, 最后生成"可执行文件". 可执行文件中保存的是二进制机器码. 这串机器码可以直接被CPU读取和执行. 

软件意义上, "指令集"实际上是一个规范, 规范汇编的文件格式.
以下为一条x86汇编代码:
mov word ptr es:[eax + ecx * 8 + 0x11223344], 0x12345678

这里可以体现出指令集的格式限制:
1. 可以使用mov指令, 但它只能有2个操作数.
2. 它的操作数长度是16 (word), 不要看到后面0x12345678就认为是32位操作数.
3. 它带有段超越前缀, 这里使用了es, 还可以使用ds, cs, ss, fs, gs. 但是只能用这几个.
4. 第一个操作数是一个内存地址, 第二个是立即数. 但是, 这个内存地址不能乱写, 写成[eax+ecx*10+0x11223344]就错了.

实际上, 一条汇编指令与一段机器码是一一对应的. 上面这段汇, 可以被x86编译器翻译成几乎唯一的一段机器码:
26 66 c7 84 c8 44 33 22 11 78 56
上面提到的1,2,3,4点如果有一个弄错, 这一步就会失败.

可以看出来, 指令集的作用, 就是告诉程序员/编译器, 汇编一定要有格式. 支持什么指令, 指令带什么限制条件, 用什么操作数, 用什么地址, 都是指令集规范的内容, 要是写错了, 就无法翻译成机器码.
指令集规范汇编, 汇编可以翻译成机器码, 机器码告诉CPU每个周期去做什么. 因此, CPU指令集是描述CPU能实现什么功能的一个集合, 就是描述"CPU能使用哪些机器码"的集合".

那机器码进入到CPU后又做什么呢?
=====================编译器和CPU的分界线========================

需要被执行的机器码先要被OS调度到内存之中, 程序执行时, 机器码依次经过了Memory--Cache--CPU fetch, 进入CPU流水线, 接着就要对它进行译码了, 译码工作生成的象是CPU内部数据格式, 微码(或者类似的格式, 这个格式不同的厂商会自己设计). 

这个过程画成图就是:

软件层: 汇编语言
------------------------------------------------------------------------
接口: 汇编语言所对应的机器码
------------------------------------------------------------------------
硬件层: CPU使用内部数据结构进行运算

如果机器码代表的功能是在指令集规范内的, 这条机器码就可以生产微码, 并在CPU内正常流动. 假设机器码是错误的, 是不可以通过CPU的译码阶段的, 控制电路一定会报错. 这种情况反映在Windows里往往都是蓝屏, 因为CPU无法继续执行, 它连下一条指令在哪都不知道.

那么指令集在CPU里就代表: 只有CPU指令集范围内的指令可以被成功的译码, 并送往CPU流水线后端去执行.
和常规的想法不一样, CPU不需要任何形式的存储介质去存储指令集, 因为"译码"这个步骤就是在对指令集里规范的机器码做解码. 硬件上, 译码这件事需要庞大数目的逻辑门阵列来实现.

跳出格式这个圈子来看待这个问题. 可以说, CPU执行单元的能力, 决定了指令集的范围. 比如, CPU的执行单元有能力执行16位加法, 32位加法, 64位加法, 那么指令集一般就会有ADD 16, ADD 32, ADD 64这样的表达方式. 如果CPU的执行单元没有电路执行AVX指令, 那么指令集一般就没有VINSERTF128这样的指令供使用. 所以, 强有力的执行单元能够提供更多的指令集.

再来看"CPU指令集在哪里"这个问题, 回答是, CPU本身就是CPU指令集指令集规定CPU可以做什么事, CPU就是具体做这件事的工具. 如果一定要指定一个狭义的CPU指令集的存放位置. 那就是CPU中的"译码电路".

再来看"CPU指令集在哪里"这个问题, 回答是, CPU本身就是CPU指令集指令集规定CPU可以做什么事, CPU就是具体做这件事的工具. 如果一定要指定一个狭义的CPU指令集的存放位置. 那就是CPU中的"译码电路".

1. 指令集是在设计CPU时规定的,指令集规定了有哪些CPU能够“一条条”执行的“指令”是合法的。
2. 指令集是一个集合,它的功能性体现在每条能够执行的“指令”上面。涉及到具体指令后,就涉及到谁是“操作对象”,和“如何找到操作对象”,“对操作对象进行什么操作”,这些问题上来。
3. 指令的功能是通过CPU中功能逻辑电路来实现的,之前的“指令设计”决定了如何进行“逻辑电路设计”。而相同的指令可以采取不同的逻辑电路设计。
4. 因为“指令集”本身没有功能性,所以在CPU中你不能找到“指令集”这个实体,但是指令集中的指令与CPU的内部晶体管组成的逻辑电路是等价的(除了指令部分还有中断,外设等这些暂不考虑),那么非要化等价的话,就是实现指令集中各指令的整体晶体管逻辑电路。
5. 如果你非要在没给出指令集的CPU来找到它的指令集的话,你可以通过修改PC指向的下一条指令的内容,并观察内存及各寄存器的变化,来试探每条指令编码的功能(这显然没有什么实际价值)(你可以用这种方法去理解指令的功能)。

指令集系统不是存放在cpu中的,它是被整合到操作系统内核最底层的hal(硬件抽象层)中的,属于操作系统与硬件之间(宏指令与微指令)的接口。它向操作系统定义了CPU最基本的功能,而操作系统执行某个任务的实质就是在调用这些功能。这就好比算一道复杂的数学题,不管题有多复杂解题的每一步都要遵循最基础的定理公式,而指令集就是计算机解题所需的定理公式。指令集系统的统一解决了不同品牌不同型号的CPU对操作系统与应用软件兼容性的问题,有了统一的指令集系统不管是I或A的CPU二者电路设计与微指令如何不同,对于windows或linux都能很好地兼容,用户买一款CPU就能使用各种软件,程序员编写软件也不用研究每款CPU中的具体电路与微指令,只需调用通用的指令集即可。
PS:这个问题是我提的,但上面的回答确实不靠谱,查了相关的资料终于有了靠谱的答案。

免责声明:文章转载自《指令集 与 cpu》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇通过iframe标签绕过csp在Centos7下安装nghttp2下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ARMGNU伪指令

符号定义伪指令 .global,.local,.set,.equ .global 使得符号对连接器可见,变为对整个工程可用的全局变量 .global symbol .local 表示符号对外部不可见,只对本文件可见 .local symbol .set 给一个全局变量或局部变量赋值,和.equ的功能一样 .set symbol expr .set s...

IOS中armv7,armv7s,arm64以及i386和x86_64讲解

一、前言问题 在iOS 开发过程中,估计比较少的人会在意armv7,armv7s,arm64这些概念,如果在意可能也是项目中出现了像下面的问题,才会想起来解决这些问题,但还是不是特别的理解,这些概念,今天写这篇博客,希望大家对这些概念有所了解。 上面的这个问题,是我用自己手机iPhone 7p真机运行的,关于配置如下: 如果出现上面的问题,我们在val...

Java内存模型(JMM)总结

Java内存模型(JMM) 我们常说的JVM内存模型指的是JVM的内存分区;而Java内存模型是一种虚拟机规范。 Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:...

汇编指令mov、add、sub、jmp

mov:寄存器,数据 mov:寄存器,寄存器 mov:寄存器,内存单元 mov:段寄存器,内存单元 mov:内存单元,寄存器 mov:内存单元,段寄存器 mov:段寄存器,寄存器 mov:寄存器,段寄存器 add:寄存器,数据 add:寄存器,寄存器 add:内存单元,寄存器 add:寄存器,内存单元 sub:寄存器,数据 sub:寄存器,寄存器 sub:...

汇编效率优化:指令处理机制

大多数情况下,编写程序都不会使用汇编语言而是使用高级语言,原因大致有以下几点: 花费更多时间。高级语言的一行相当于汇编语言的几行、几十行甚至更多。 不够安全。比如说在进行函数调用时PUSH与POP必须成对出现,高级语言中的函数调用会自动为你执行PUSH与POP的操作,但是汇编语言中就必须由程序员自己保证PUSH与POP一致,否则会导致栈错乱,使得程序出现...

函数的调用过程与出入栈

函数调用的过程 线程执行的基本行为是函数调用,每次函数调用的数据都是通过Java栈传递的。Java栈与数据结构上的栈有类似的含义,它是一块先进后出的数据结构,只支持入栈和出栈两种操作。Java栈的主要内容是栈帧。每次函数调用都会有一个对应的栈帧被压入Java栈,每次函数调用结束(无论是正常返回或者抛出异常),都会有一个栈帧被弹出Java栈。 如图所示,函数...