(已更正) 这个问题包括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中一个指令集或者多个指令集才能完成的任务,那么不同的指令集效率也不同。
X86指令集在执行上海到北京的任务时,方式是坐飞机,ARM指令集则是坐火车,不同任务在不同的指令集下执行效率是不一样的,此时X86可能更快些。但如果任务换成做一顿丰盛的大餐,可能ARM更快一些。
比如此时我设计了一套非常牛逼的指令集,就叫NB指令集吧,它执行上海到北京的任务的方式是“闪现”,那么效率就碾压X86和ARM,我将走向人生巅峰。
与此同时,我的一位同事也设计了另一套指令集,简称FW指令集。但这套指令集从北京到上海采用的方式是“疾跑”,结果不仅效率差,还异常耗电,没有多久这个CPU就挂了,几个月后,我这个同事就被裁了。
还有,我的另一位同事也设计了一套指令集,简称LJ指令集,这套指令集非常失败,无法实现上海到北京的任务,因为他没去过北京也不知道北京怎么走,结果被老板边缘化,半年后就去投奔前一个被裁的同事去了。因为那个被裁的同事在新公司拿了double的薪资。
所以回过头来看,坐飞机、乘高铁、用闪现、疾跑,以及去不了北京这些方式存在什么地方吗?并没有,但是要实现这些方式,你得有飞机、机场、高铁、车站、飞毛腿等设施,而这些设施的本质,就是CPU的晶体管电路本身。
CPU是某个特定的指令集在硬件上的实现。它本身并不知道为什么要这么做,也不知道它在做什么,它存在的终极目的就是“实现”这个指令集。
9月21日,美国总统拜登在和英国首相约翰逊的会面中,突然毫无预兆的要求记者清场,而在那段现场的视频中,似乎有一记者问了一句:“Did he shit?”(“他是不是拉了?”),而旁边的另一位记者回道:"I have no idea,hope the microphone got it。"(“我也不知道,但愿麦克录到了。”)
这段视频流出之后,全世界的舆论场都炸了锅,人们纷纷怀疑,已经是80高龄的拜登,是否在这样严肃的场合,一个不小心,拉在了裤子里,所以才会突然要求清场,而现场的记者是闻到了味道或者听到了声音,才会有此一问。
这个看似荒谬的猜测,却意外的流传极广,以至于向来标榜言论自由的外网都开始大量封杀此类帖文,而美国官方也很快出来辟谣说清场跟总统拜登的身体情况无关,只是出于政治和外交因素,两位领导人必须密谈。
但网民们可不管这么多,美国政府越是删帖和澄清,他们就越是对拜登的“脱粪”深信不疑,传言越传越是有板有眼,之前俄罗斯总统普京的那句“祝他身体健康”也被拉出来反复分析,进一步佐证了拜登的“失禁症状”。
这个曾经代表着“战无不胜,众望所归”的超级大国和世界第一强国,居然以如此不体面的方式迎来了舆论的毁灭性打击,这让许多美国的敌人和反对者都大为诧异。
然而,冷静下来思考,我们会发现,这其中疑点颇多,因为在那段广为流传的视频中,第一位记者在提出疑似脱粪的疑问之后,另一位记者给她的回复是“我希望麦克风录了下来”,如果真的是拉裤子这种事情,被麦克风录下来的可能性实在太小,还不如说希望摄像头拍到了。
即便退一万步,认定确实是拜登没有控制住大小便,但其实他作为一个80岁的老人,出现这种情况也并不稀奇,衰老并不是罪恶,也不至于为此如此残酷的嘲笑一位老人。
因此,拜登如今的被群嘲,可以说只是美国国力衰退的一个缩影,无论拜登是否真的大小便失禁,但他作为美国总统,领导着这个衰退的美国一路火花带闪电的跌下了神坛,曾经的荣耀必然会一道一道全部化作孽力反馈回他的身上。
简而言之就是,如果美国今日没有从阿富汗撤军,新冠也已经完全被控制,那么拜登就是拉的到处都是,也依然会有人跪舔说他这就像廉颇“一饭三遗矢”,是有大将之风,可当美国撤出阿富汗,新冠病死七十万之后,哪怕他这位总统日日正襟危坐,我们也总会怀疑,他屁股底下,是不是粘着什么不雅的东西。
这,就是今日的世界,就是美国从“谁也打不过”到“谁也打不过”之后,所必须要面对的残酷现实啊。