54

在过去的 3 到 5 年里,我一直在使用 C 和 CPython。考虑一下我的知识基础。

如果我要对支持它的处理器使用汇编指令,MOV AL, 61h那么处理器内部究竟是什么来解释这段代码并将其作为电压信号发送?这么简单的指令怎么可能执行?

当我尝试考虑包含在MOV AL, 61h甚至XOR EAX, EBX.

编辑:我读了一些评论,问为什么当 x86 系列在嵌入式系统中不常见时我把它作为嵌入式。欢迎来到我自己的无知。现在我想,如果我对此一无所知,那么可能还有其他人对此一无所知。

考虑到你们都为答案付出的努力,我很难选择一个最喜欢的答案,但我觉得有必要做出决定。没有受伤的感觉,伙计们。

我经常发现,我对计算机了解得越多,我意识到自己真正了解的就越少。感谢您让我对微码和晶体管逻辑敞开心扉!

编辑#2:感谢这个线程,我刚刚理解了为什么XOR EAX, EAXMOV EAX, 0h. :)

4

12 回答 12

40

我最近开始阅读 Charles Petzold 的名为 Code 的书,到目前为止,这本书涵盖了我认为你会好奇的那些事情。但是在购买/借阅之前,我还没有完全通读这本书。

这是我相对简短的回答,而不是 Petzolds ......希望与您的好奇心一致。

你听说过我假设的晶体管。最初使用晶体管的方法是用于晶体管收音机之类的东西。它基本上是一个放大器,将漂浮在空气中的微小无线电信号馈入晶体管的输入端,该晶体管打开或关闭旁边电路上的电流。然后你用更高的功率连接那个电路,这样你就可以接收一个非常小的信号,放大它并将其馈入扬声器,例如收听广播电台(还有更多的事情是隔离频率并保持晶体管平衡,但是你明白我希望的想法)。

现在晶体管的存在导致了一种使用晶体管作为开关的方法,就像电灯开关一样。收音机就像一个调光开关,你可以把它调到任何地方,从一直开到一直关。非调光灯开关要么全部打开,要么全部关闭,开关中间有一个神奇的地方,它可以转换。我们在数字电子产品中使用晶体管的方式相同。取一个晶体管的输出并将其馈入另一个晶体管输入。第一个晶体管的输出肯定不是无线电波那样的小信号,它迫使第二个晶体管一直打开或关闭。这导致了TTL或晶体管晶体管逻辑的概念。基本上,您有一个晶体管驱动高压,或者称其为 1,然后在其上吸收零电压,我们称其为 0。并且您将输入与其他电子设备一起安排,以便您可以创建与门(如果两个输入均为 1,则输出为 1),或门(如果一个或另一个输入为 1,则输出为 1) . 反相器、与非门、门、或非门(一个或带有反相器)等。曾经有一本 TTL 手册,你可以购买 8 个左右的引脚芯片,这些芯片有一个或两个或四个某种门(NAND、NOR、 AND等)内部功能,两个输入和一个输出。现在我们不需要那些用数百万晶体管创建可编程逻辑或专用芯片更便宜的东西。但是我们仍然在硬件设计中考虑 AND、OR 和 NOT 门。(通常更像是 nand 和 nor)。或门(如果一个或另一个输入为 1,则输出为 1)。反相器、与非门、门、或非门(一个或带有反相器)等。曾经有一本 TTL 手册,你可以购买 8 个左右的引脚芯片,这些芯片有一个或两个或四个某种门(NAND、NOR、 AND等)内部功能,两个输入和一个输出。现在我们不需要那些用数百万晶体管创建可编程逻辑或专用芯片更便宜的东西。但是我们仍然在硬件设计中考虑 AND、OR 和 NOT 门。(通常更像是 nand 和 nor)。或门(如果一个或另一个输入为 1,则输出为 1)。反相器、与非门、门、或非门(一个或带有反相器)等。曾经有一本 TTL 手册,你可以购买 8 个左右的引脚芯片,这些芯片有一个或两个或四个某种门(NAND、NOR、 AND等)内部功能,两个输入和一个输出。现在我们不需要那些用数百万晶体管创建可编程逻辑或专用芯片更便宜的东西。但是我们仍然在硬件设计中考虑 AND、OR 和 NOT 门。(通常更像是 nand 和 nor)。现在我们不需要那些用数百万晶体管创建可编程逻辑或专用芯片更便宜的东西。但是我们仍然在硬件设计中考虑 AND、OR 和 NOT 门。(通常更像是 nand 和 nor)。现在我们不需要那些用数百万晶体管创建可编程逻辑或专用芯片更便宜的东西。但是我们仍然在硬件设计中考虑 AND、OR 和 NOT 门。(通常更像是 nand 和 nor)。

我不知道他们现在教什么,但概念是一样的,对于内存来说,触发器可以被认为是两个这样的 TTL 对(NANDS),一个的输出连接到另一个的输入。就这样吧。这基本上是我们所说的 SRAM 或静态 ram 中的一个位。sram 基本上需要 4 个晶体管。Dram 或动态 ram 您自己放入计算机的记忆棒每比特需要一个晶体管,因此对于初学者,您可以了解为什么 DRAM 是您购买千兆字节的东西。只要电源不熄灭,Sram 位就会记住您将它们设置为什么。当你告诉它时,Dram 开始忘记你告诉它的内容,基本上 dram 以第三种不同的方式使用晶体管,有一些电容(如电容器,不会在这里进入),就像一个微型可充电电池,一旦你给它充电并拔下充电器,它就会开始耗尽。想一想架子上的一排玻璃杯,每个玻璃杯上都有小孔,这些都是你的酒杯,你想要其中一些是杯子,所以你有一个助手来装满你想成为的杯子。那个助手必须不断地把水罐装满,然后往下走,让“一”位的杯子装满水,让“零”位的杯子保持空着。因此,任何时候您想查看您的数据是什么,您都可以通过查找绝对高于中间的水位为 1 和绝对低于中间的水位为零来查看并读取 1 和 0。所以即使通电时,如果助手不能让眼镜保持足够满以区分 1 和 0,它们最终会看起来像 0 并耗尽。这是每个芯片更多位的权衡。简短的故事是,在处理器之外,我们使用 dram 作为大容量内存,并且有辅助逻辑负责将 1 保持为 1,将 0 保持为 0。但是在芯片内部,例如 AX 寄存器和 DS 寄存器使用触发器或 sram 来保存您的数据。对于您所知道的每一位,例如 AX 寄存器中的位,可能有成百上千或更多用于将这些位进出该 AX 寄存器。并且有一个辅助逻辑负责将 1 保持为 1,将 0 保持为 0。但是在芯片内部,例如 AX 寄存器和 DS 寄存器使用触发器或 sram 来保存您的数据。对于您所知道的每一位,例如 AX 寄存器中的位,可能有成百上千或更多用于将这些位进出该 AX 寄存器。并且有一个辅助逻辑负责将 1 保持为 1,将 0 保持为 0。但是在芯片内部,例如 AX 寄存器和 DS 寄存器使用触发器或 sram 来保存您的数据。对于您所知道的每一位,例如 AX 寄存器中的位,可能有成百上千或更多用于将这些位进出该 AX 寄存器。

您知道处理器以某种时钟速度运行,如今大约为每秒 2 GHz 或 20 亿时钟。想想时钟,它是由晶体产生的,另一个话题,但逻辑认为该时钟是一个电压,在这个时钟频率 2ghz 或其他任何情况下会变高、变高和变为零(gameboy 前进是 17mhz,旧 ipod 大约是 75mhz,原装 ibm pc 4.77mhz)。

因此,用作开关的晶体管允许我们获取电压并将其转换为我们作为硬件工程师和软件工程师都熟悉的 1 和 0,甚至可以为我们提供 AND、OR 和 NOT 逻辑功能。我们有这些魔法水晶,可以让我们获得准确的电压振荡。

所以我们现在可以做一些事情,比如说,如果时钟是一个,并且我的状态变量说我处于获取指令状态,那么我需要切换一些门,以便我想要的指令的地址,它在程序计数器,在内存总线上熄灭,以便内存逻辑可以给我关于 MOV AL,61h 的指令。您可以在 x86 手册中查找此内容,并发现其中一些操作码位表示这是一个 mov 操作,目标是 EAX 寄存器的低 8 位,而 mov 的源是立即值,这意味着它在这条指令之后的内存位置。所以我们需要将该指令/操作码保存在某处,并在下一个时钟周期获取下一个内存位置。所以现在我们保存了mov al,

你问这一切是怎么发生的?想想一个 python 函数执行一些数学公式。您从程序的顶部开始,将一些作为变量输入的公式输入到程序的各个步骤中,这些步骤可能会在此处添加一个常量或从库中调用平方根函数等。在底部您返回答案。硬件逻辑以相同的方式完成,今天使用的编程语言看起来很像 C。主要区别在于您的硬件功能可能有数百或数千个输入,而输出是一位。在每个时钟周期,AL 寄存器的第 0 位都在使用一个庞大的算法进行计算,具体取决于您想要查看的距离。想想你为数学运算调用的平方根函数,该函数本身就是其中之一,一些输入会产生输出,它可能会调用其他函数,可能是乘法或除法。因此,您可能在某个地方可以将其视为 AL 寄存器的第 0 位之前的最后一步,其功能是:如果时钟为 1,则 AL[0] = AL_next[0]; 否则 AL[0] = AL[0]; 但是有一个更高的函数包含从其他输入计算的下一个 al 位,一个更高的函数和一个更高的函数,其中大部分是由编译器创建的,就像你的三行 python 可以变成数百或数千的汇编程序行。几行 HDL 可以变成成百上千甚至更多的晶体管。硬件人员通常不会查看特定位的最低级别公式来找出所有可能的输入以及计算所需的所有可能的 AND 和 OR 和 NOT,而不是您可能检查程序生成的汇编程序。但如果你愿意,你可以。

关于微编码的说明,大多数处理器不使用微编码。例如,您使用 x86 进入它是因为它在当时是一个很好的指令集,但表面上很难跟上现代的步伐。其他指令集不需要微编码,直接按照我上面描述的方式使用逻辑。您可以将微编码视为使用不同指令集/汇编语言的不同处理器,它模拟您在表面上看到的指令集。不像你在mac上模拟windows或在windows上模拟linux等复杂。微编码层是专门为这项工作设计的,你可能会认为只有四个寄存器AX、BX、CX、DX,但那里里面还有很多。自然地,一个汇编程序可以在一个或多个内核的多个执行路径上执行。就像闹钟或洗衣机中的处理器一样,微码程序简单而小巧,可以调试并烧录到硬件中,希望永远不需要固件更新。至少理想情况下。但就像您的 ipod 或手机一样,您有时确实需要修复错误或其他任何东西,并且有一种方法可以升级您的处理器(BIOS 或其他软件在启动时加载补丁)。假设您打开电视遥控器或计算器的电池盒,您可能会看到一个孔,您可以在其中看到一些裸露的金属触点,可能是三个或五个或更多。对于某些遥控器和计算器,如果您真的想要,您可以重新编程,更新固件。不过一般不会,理想情况下,遥控器完美或完美到足以比电视机寿命长。微编码提供了在市场上获得非常复杂的产品(数百万、数亿晶体管)并修复该领域中可修复的大错误的能力。想象一下,你的团队在 18 个月内编写了一个 2 亿行的 Python 程序,并且必须交付它,否则公司将无法参加竞赛产品。类似的事情,除了你可以在现场更新的一小部分代码之外,其余部分必须保持不变。对于闹钟或烤面包机,如果有错误或需要帮助的东西,您只需将其扔掉并获取另一个。数以亿计的晶体管)在市场上,并在未来修复该领域中的大且可修复的错误。想象一下,你的团队在 18 个月内编写了一个 2 亿行的 Python 程序,并且必须交付它,否则公司将无法参加竞赛产品。类似的事情,除了你可以在现场更新的一小部分代码之外,其余部分必须保持不变。对于闹钟或烤面包机,如果有错误或需要帮助的东西,您只需将其扔掉并获取另一个。数以亿计的晶体管)在市场上,并在未来修复该领域中的大且可修复的错误。想象一下,你的团队在 18 个月内编写了一个 2 亿行的 Python 程序,并且必须交付它,否则公司将无法参加竞赛产品。类似的事情,除了你可以在现场更新的一小部分代码之外,其余部分必须保持不变。对于闹钟或烤面包机,如果有错误或需要帮助的东西,您只需将其扔掉并获取另一个。

如果您浏览 wikipedia 或只是 google 资料,您可以查看指令集和机器语言,例如 6502、z80、8080 和其他处理器。可能有 8 个寄存器和 250 条指令,您可以从晶体管的数量中感受到,与每个时钟计算触发器中每个位所需的逻辑门序列相比,这 250 条汇编指令仍然是一种非常高级的语言循环。你的假设是正确的。除了微编码处理器,这种低级逻辑不能以任何方式重新编程,您必须使用软件修复硬件错误(对于即将交付或将交付但未报废的硬件)。

看看 Petzold 的那本书,他在解释东西方面做得非常出色,远胜于我所能写的任何东西。

于 2010-09-14T23:01:09.177 回答
19

编辑:这是一个 CPU (6502) 的例子,它已经在晶体管级别使用 python/javascript 模拟了http://visual6502.org你可以把你的代码放进去看看它是如何做的。

编辑:出色的 10 000 米水平视图: 新机器的灵魂 - 特蕾西·基德

在我进行微编码之前,我很难想象这一点。然后这一切都说得通了(抽象地)。这是一个复杂的话题,但从一个非常非常高的角度来看。

基本上是这样想的。

CPU 指令本质上是存储在构成内存的电路中的一组电荷。有一些电路会导致这些电荷从内存转移到 CPU 内部。一旦进入 CPU,电荷就会被设置为 CPU 电路布线的输入。这本质上是一个数学函数,它将导致更多的电输出发生,并且循环继续。

现代 CPU 要复杂得多,但包含许多微编码层,但原理保持不变。记忆是一组电荷。有移动电荷的电路和执行功能的其他电路将导致其他电荷(输出)馈送到存储器或其他电路以执行其他功能。

要了解内存的工作原理,您需要了解逻辑门以及它们是如何由多个晶体管创建的。这导致发现硬件和软件在本质上执行数学意义上的功能的意义上是等价的。

于 2010-09-14T04:04:19.280 回答
14

这个问题需要的不仅仅是 StackOverflow 上的答案来解释。

要了解从最基本的电子元件到基本机器代码的所有方法,请阅读Horowitz 和 Hill 的 The Art of Electronics。要了解有关计算机体系结构的更多信息,请阅读Patterson 和 Hennessey 的计算机组织和设计。如果您想了解更高级的主题,请阅读Hennessey 和 Patterson 所著的 Computer Architecture: A Quantitative Approach

顺便说一句,电子艺术也有配套的实验室手册。如果您有可用的时间和资源,我强烈建议您进行实验室;实际上,我参加了 Tom Hayes 教授的课程,其中我们构建了各种模拟和数字电路,最终用 68k 芯片、一些 RAM、一些 PLD 和一些分立元件构建了一台计算机。您可以使用十六进制键盘将机器代码直接输入 RAM;这是一次爆炸,也是获得计算机最低级别经验的好方法。

于 2010-09-14T04:04:45.473 回答
13

没有整本书就不可能详细解释整个系统,但这里有一个简单计算机的非常高级的概述:

  • 在最低层有物理和材料(例如由掺杂硅制成的晶体管)。
  • 使用物理和材料,您可以推导出NAND 逻辑门
  • 使用 NAND 门,您可以派生所有其他基本逻辑门(AND、OR、XOR、NOT 等),或者为了提高效率,直接从晶体管构建它们,包括具有 2 个以上输入的版本。
  • 使用基本逻辑门,您可以推导出更复杂的电路,例如加法器多路复用器等。
  • 同样使用基本逻辑门,您可以导出有状态的数字电路元件,例如触发器时钟等。
  • 使用更复杂的状态电路,您可以导出更高级别的部分,如计数器内存寄存器算术逻辑单元等。
  • 现在你只需要将你的高级部分粘合在一起,这样:
    • 值超出内存
    • 通过使用多路复用器等将值分派到适当的位置(例如 ALU 或内存),该值被解释为指令。(基本指令类型是从内存读取到寄存器,从寄存器写入到-内存、寄存器执行操作和条件跳转指令。)
    • 该过程重复下一条指令

要了解汇编指令如何导致电压变化,您只需了解这些级别中的每一个如何由以下级别表示。例如,一条 ADD 指令将导致两个寄存器的值传播到 ALU,ALU 具有计算所有逻辑运算的电路。然后另一侧的多路复用器从指令中输入 ADD 信号,选择所需的结果,该结果会传播回其中一个寄存器。

于 2010-09-15T21:48:24.857 回答
8

这是一个很大的问题,在大多数大学里都有一整个学期的课程来回答这个问题。所以,与其在这个小盒子里给你一些可怕的总结,我会引导你看一本包含全部真相的教科书:计算机组织和设计:Patterson 和 Hennessey 的硬件/软件接口

于 2010-09-14T04:01:27.040 回答
7

一个更简单的介绍,但仍然很好地介绍了从电线开始的计算机
http://img.amazon.com/images/I/31GBgcA5PML._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU15_.jpg

Charles 的 Petzold 代码

于 2010-09-14T04:07:01.803 回答
5

非常简短,

机器代码指令作为一系列位存储在处理器中。如果您在处理器数据表中查找MOV,您会看到它有一个十六进制值,例如(例如)0xA5,这是特定于MOV指令的。(有不同类型的MOV指令具有不同的值,但让我们忽略暂时这样)。

0xA5 hex == 10100101 binary.

*(这不是MOVX86 上的真正操作码值 - 我只是为了说明目的选择一个值)。

在处理器内部,它存储在一个“寄存器”中,它实际上是一个触发器或锁存器的阵列,用于存储电压:

+5 0 +5 0 0 +5 0 +5

这些电压中的每一个都馈入门或门集合的输入。

在下一个时钟沿,这些门根据来自寄存器的输入电压更新它们的输出。

这些门的输出馈送到另一级门,或返回到它们自己。该级别馈入下一个级别,该级别馈入下一个级别,依此类推。

最终,沿线路的门输出将连接回另一个锁存器/触发器(内部存储器),或处理器上的一个输出引脚。

Register->(clock)->Gate A->(clock)->Gate B->pin
                                          ->latch

(忽略不同门类型和更高级别结构的反馈)

这些操作在一定程度上由核心架构定义并行发生。“更快”的处理器(例如 2.0GHz 与 1.0GHz)性能更好的原因之一是更快的时钟速度(GHz 值)导致从一个门集合到下一个门的更快传播。

重要的是要理解,在非常高的层次上,处理器所做的只是改变引脚电压。我们在使用诸如 PC 之类的设备时看到的所有光荣的复杂性都源自门的内部模式以及连接到处理器的外部设备/外围设备(如其他 CPU、RAM 等)的模式。处理器是其引脚改变电压的模式和序列,以及允许 CPU 某一时刻的状态影响其下一时刻的状态的内部反馈。(在汇编中,这种状态由标志、指令指针/计数器、寄存器值等表示)

以一种非常真实的方式,每个操作码(机器代码指令)的位在物理上与处理器的内部结构相关联(尽管这可能在必要时通过内部查找表/指令映射在一定程度上抽象出来)。

希望有帮助。我还接受过很好的 EE 教育和大量嵌入式开发经验,所以这些抽象对我来说很有意义,但对新手来说可能不是很有用。

于 2010-09-16T15:46:02.310 回答
1

数字电路中最基本的元素应该是逻辑门。逻辑门可用于构建逻辑电路以执行布尔算术或解码器,或触发器等时序电路。触发器可以被认为是 1 位存储器。它是更复杂的时序电路的基础,例如计数器或寄存器(位阵列)。

微处理器只是一堆定序器和寄存器。对微处理器的“指令”不仅仅是按顺序推送到某些寄存器上的位模式,以触发特定序列以对“数据”执行计算。数据表示为位数组......现在我们处于更高的水平。

于 2010-09-14T04:30:44.827 回答
1

好吧,这是一个非常糟糕的总结:-)

MOV AL, 61h 也是一种人类可读的代码形式,它被输入到汇编器中。汇编器生成等效的十六进制代码,它基本上是处理器可以理解的字节序列,也是您将存储在内存中的内容。在在嵌入式系统环境中,链接器脚本为您提供了关于将这些字节(用于程序/数据等的单独区域)放置在内存中的位置的细粒度控制。

处理器本质上包含一个使用触发器实现的有限状态机(微代码)。机器从内存中读取(获取周期)“MOV”的十六进制代码,计算出(解码周期)它需要一个操作数,在本例中为 61h,再次从内存中获取它,并执行它(即复制 61进入累加器寄存器。'Read''fetch',execute'等都意味着使用加法器,减法器,多路复用器等数字电路将字节移入和移出移位寄存器

于 2010-09-14T10:03:29.400 回答
1

《微处理器设计》一书的草稿目前在 Wikibooks 上在线提供。

我希望有一天它会对这个问题提供一个很好的答案。同时,也许您仍然可以从当前对该问题的答案草稿中学到一些东西,并帮助我们进行改进或至少指出我们忘记解释的内容以及解释令人困惑的地方。

于 2010-09-16T15:32:48.870 回答
0

解释此代码并将其作为电压信号发送的处理器内部究竟是什么

我想说“硬件”,但更真实的答案是“微码”。

于 2010-09-14T15:28:23.340 回答
0

我一直在想它,疯狂地搜索。人们回答诸如“bla bla writes to RAM”之类的问题,但我真的对“write”的含义很感兴趣。

你总是从输入代码开始,对吧?然后编译,组装,机器代码等......它如何变成晶体管上的电压?可是等等!让我们在这里退一步。当您输入代码时,假设您想用任何语言编写“print 'Hello World'”。当您在键盘上按下“p”(“print”的第一个字母)时,您实际上是在重新路由由墙壁插座提供的电流,该电流通过某个路径流向某组晶体管。因此,您实际上已经在此步骤中存储了 0V 和 +5V。不是后期生成的!

这些电压在后面的步骤中是如何被冲洗掉的,这很好……各个层面的电气科学。

希望这能回答你的问题。

于 2015-09-22T08:36:02.607 回答