我们如何准确地从二进制/十六进制转换为汇编指令集?


13

因此,我最近一直在这里尝试学习一些嵌入式/汇编编程,并且甚至尝试学习最低级别的知识(门等)。

不过,有一件事使我感到困惑……是如何“获得”指令集。我在某种程度上了解gates / TTL等的工作原理,但是我看不到如何从中获取mov,add,clr等...?

这可能是一个愚蠢的问题....但是我的意思是我回想起第一个微处理器/控制器,并认为..他们究竟是如何设计指令集并使之工作的?

编辑:我想为清晰起见,假装我在谈论第一个微处理器,它们是如何从二进制转换为实际创建指令集的?


2
每个指令都有一个值,编译器会根据您的代码结构将您的代码转换为这些指令。
Ramhound 2011年

1
我不确定我是否完全理解您的问题,但是我认为您可以在此处此处此处找到答案。
e-MEE


3
他们是如何从Binary转到实际创建指令集的? 实际上,“他们”没有-至少是相反。CPU设计人员确定CPU将执行的操作,然后从中创建指令集,然后将指令(助记符)映射到操作码(二进制机器码)。@Scott Whitlock在下面提供了一个很好的答案,我只是想解决您问题的最后一部分,因为至少从我的经验来看,您的假设是落后的。
Radian

1
这本非常不错的书:www1.idc.ac.il/tecs向我解释了这一切,大部分章节都可以在线免费获得。您可以使用nand gates(用简单的硬件描述语言)设计自己的芯片,然后是汇编器,然后是编译器,然后用您创建的语言编写os!令人赞叹的东西,作为一个没有理科学位的人,这是我度过的时间!
bplus 2012年

Answers:


18

CPU的核心是ALU。它负责接收一条指令(如MOV),该指令只是一些预定义的二进制数字系列,还接收0、1或2个操作数,并对它们执行适用的操作。最简单的指令可以是NOP(无操作),它实际上什么也不做。另一个典型的操作是ADD(相加两个值)。

ALU从“寄存器”读取数据并将数据写入“寄存器”。这些是CPU内部的小内存位置。指令的一部分(每个输入2至3位,具体取决于您拥有的寄存器数量)指示要读取的寄存器。ALU外部的CPU中有一些单元,用于将所需的数据(和指令)从存储器中加载到寄存器中,并将寄存器中的结果写回到存储器中。写结果的位置也将被编码为另外的2或3位。

“操作码”(代表操作的二进制数)的选择不是任意的。精心选择的操作码可降低ALU的复杂性。每个位或位组都倾向于启用和禁用ALU中的某些逻辑门。例如,一条ADD指令必须使输出级能够选择内部加法逻辑的结果。同样,一条MUL指令将选择乘法逻辑的结果。根据设计的不同,加法器和乘法电路很可能实际上都在输入操作数上执行其操作,而只是输出选择(写入ALU的输出位的内容)会发生变化。


1
我想我问的是,他们如何选择?他们实际上如何进行分配?

1
@索伦:再次重读第三段,并尝试理解二进制算术和数字电路。我可以用数字电路中的8位线表示256条指令的指令集。这意味着我需要在硬件设备上使用8个io端口来传输每个可能的状态(每行2个状态^ 8行= 256个可能状态)。然后,处理单元可以决定如何处理该数字输入信号。数字电路意味着您具有两种硬件状态:高和低,电压或无电压。那就是二进制文件的来源。二进制表示是最接近金属的表示。
猎鹰

3
@Sauron-查找数字多路复用器,以查看数字电路如何从多个值之一中进行选择。如果您有8位总线,则只需并行使用8个这些二进制数字多路复用器。
Scott Whitlock

1
@Falcon好吧.......我认为这更有意义。我一直忘了,最后所有这些都归结为二进制信号……,甚至“ mov”之类的指令仍然表示为二进制。

1
@Sauron-对CPU进行一些研究,它将帮助您了解什么是操作码以及它们如何工作。为什么选择某些操作码并不重要,即使问“为什么”问题也不是很有意义。了解如何选择它们可能有助于您更多地了解CPU及其结构。
Ramhound

9

我会从字面上回答您的问题,并且主要讨论微处理器,而不是一般的计算机。

所有计算机都有某种机器代码。一条指令由一个操作码和一个或多个操作数组成。例如,用于Intel 4004(第一个微处理器)的ADD指令编码为1000RRRR,其中1000是ADD的操作码,RRRR表示寄存器号0-15(二进制为0000-1111)。

引用16个4位寄存器之一的所有其他指令(例如INC,ISZ,LD,SUB,XCHG)也使用低4位对寄存器号进行编码,并使用高4位的各种编码来指定操作码。例如,ADD,SUB,LD和XCHG使用操作码1000、1001、1010和1011(全部为二进制)与寄存器字段组合。因此,您可以看到如何使用模式来简化逻辑。

最早的计算机程序是手工编写的,对1和0进行手工编码以创建机器语言的程序。然后将其编程到ROM(只读存储器)中。现在,对于微控制器,通常将程序写入电可擦除闪存中;如果是微处理器,则将程序用尽RAM。(后者仍需要某种只读内存来引导。)

机器语言很快变得乏味,因此开发了汇编程序,该程序采用助记符汇编语言并将其(通常每条指令一行汇编代码)转换为机器代码。因此,将写入ADD R1而不是10000001。

但是第一个汇编程序必须用机器代码编写。然后可以将其重写为自己的汇编代码,并且使用机器语言版本进行首次汇编。之后,程序可以自行组装(这称为引导)。

由于第一个微处理器是在大型机和小型计算机问世之后才开发的,而且4004确实不适合运行汇编程序,因此Intel可能编写了在其大型计算机上运行的交叉汇编程序,并为以下程序翻译了汇编代码:将4004转换为二进制图像,可以将其编程到ROM中。


4

级别很低的计算机可以用数据路径控件来表示。一起搜索这些内容可能会给您带来很多帮助,因为它是数字体系结构/设计的基础。

我会尽力总结一下:

如此处所述,从本质上讲,我们有一个ALU-关于ALU(以及CPU的其他部分)需要知道的是,它可以针对不同的操作进行重新配置。更具体地说,我们具有重新配置数据路径的能力,这就是如何获取参数,执行哪些操作以及之后将它们存储在何处。想象一下能够操纵这三件事-这是我们的控制

那么我们如何做到这一点呢?如前所述,我们可以利用低级数字逻辑并为不同路径创建多路复用器。多路复用器使用一组输入位进行控制-这些位取自哪里?从指令本身编码。要点:诸如mov,add等指令只是一组位,它们告诉CPU如何为特定操作配置其数据路径。您正在读取(移动,添加)的是人类可读的形式(汇编语言),并且我们的程序定义了数据路径和操作的过程。

如果这对那些在该领域知识渊博的人来说过于简化了更复杂的流程,我深表歉意。仅供参考,电气工程堆栈交换将是一个很好的问这个问题的地方,因为它处理的逻辑很低。


3

如果我理解您的问题,我将不了解bin / hex或程序集之间的关系。

我认为您要问的问题是如何从基本的门AND(或)中获取信息,而不是诸如移动,加载,存储,添加等说明。

我有一个从头开始制作的小教学集,其中包含一些细节内容,例如说如何从基本门进行加法和减法以及类似http://github.com/dwelch67/lsasim之类的事情。

在Petzold上查找《 Code(something something)》一书。可能从入门开始,但会慢慢将您从与计算机和电子产品无关的一切变成二进制,十六进制和基本门等。

您是在问今天如何从头开始构建一个,还是在今天又是如何做到的?今天,您将从定义指令集开始。您只是坐下来写出来,考虑一下必须具有加载,存储,移动和铝质内容的指令类型,然后是多少个寄存器,多少寄存器,这部分地影响了指令的大小,您认为关于指令大小...

让我停下来,问你如何编写程序?从文本编辑器上的空白屏幕开始?您对正在尝试解决可能需要的变量,函数,编程语言等的任务有所了解。每个人都是不同的,但是在某种程度上您会做一些(例如定义和编写函数),一小部分(使头文件具有可重用的定义,枚举,结构和填充物),另一小部分(仅代码,用变量和代码填充函数)。然后,您围绕着不同的任务进行了循环,最终,您感觉到了代码大小,速度,可读性,质量,功能等之间的平衡。硬件设计没有什么不同。硬件设计人员也使用编程语言(vhdl,verilog)并经历相同的过程,

就像提出一个软件程序一样,您可以在需求,性能,大小,功能等方面取得平衡。您可能会强迫自己想要某些设计规则,或者老板要让您这样做,等等。将初始设计转化为实现,您可能会发现自己犯了一些大错误,必须回到初始设计并更改指令集,无论大小变化。到目前为止,可能只有一个编译器和一个模拟处理器才能发现您确实需要一些特定的指令,这些指令可以显着提高编译后的代码的质量,性能等。

因此,您是从头开始发明了一些指令集,并具有一些硬件设计经验,可以将具有相似位模式的相似指令分组,以便可以更轻松地对它们进行解码,这不仅适用于硬件语言编程,还可以节省功耗和门限以及所有这些好东西。如今,您会制作某种模拟器,我的理解是ARM首先是软件模拟器,然后才进行硬件设计,不知道那是真的,而是坚持那个故事。这取决于团队,有些团队可能只是硬件人员,只想开始在hdl中进行编程,而像我这样的团队可能要兼而有之。如今,可以使用优质的硬件语言模拟器,因此您不必构建任何要编译和模拟的硬件,也无需使用硬件模拟程序/软件包进行大量调试。软件团队可以为指令集开发汇编器和编译器,并使用模拟的ram和rom feed程序向模拟处理器进行处理,并逐步进行开发。我们在不久前使用的处理器上模拟了完整的linux引导,这花费了很多小时,但仍有效(以这种方式在逻辑中找到了一个缓存错误)。

所以现在我真的想你在问什么。您如何从基本的门到带有指令集的处理器。好吧,基本的“与”,“或”或“非”不是真正的模拟,它们没有时间概念,您不能立即改变输入上的电压,而随着电压的改变,输出开始改变。门由晶体管组成,晶体管是放大器,将输入乘以某个数量,并让另一端流过那么多电流。当我们将它们用作逻辑门时,实际上是使它们过饱和,输入电压太高或太低,以致晶体管只能驱动最大电压或不能驱动电压(电流)。基本上,运输车变成了开关。长话短说,没有时间观念。为了拥有指令集,我们必须让指令发生,以便我们必须对程序进行排序,我们必须有一个概念,现在我们正在使用该指令,在下一个时隙中,我们将处理该指令。就像将放大器变成开关的游戏一样,使用带有时钟的基本逻辑门也可以玩类似的游戏。时钟来自罐中的魔晶(不值得在这里使用),使电压以固定的速率开启和关闭。在逻辑方程式中使用该电压,您就可以开始对事物进行排序。时钟来自罐中的魔晶(不值得在这里使用),使电压以固定的速率开启和关闭。在逻辑方程式中使用该电压,您就可以开始对事物进行排序。时钟来自罐中的魔晶(不值得在这里使用),使电压以固定的速率开启和关闭。在逻辑方程式中使用该电压,您就可以开始对事物进行排序。

非常简单地考虑一下这个真值表:

0 0 0
0 1 1
1 0 1
1 1 0

以二进制形式:

0 + 0 = 1
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10 (2 decimal)

上面的真值表仅着眼于一个位加法器lsbit,描述了一个位加法器。它还描述了XOR门。一个输入为真,另一输入为真。

要获得一个以上的位,您必须查看进位进位和进位,并且您需要一个三位加法器两个操作数以及一个带有两个输出的进位,进位和结果位。一旦有了三个输入两个输出加法器,就可以级联任意多的宽度。但这仍然是模拟的,闸门立即改变。

如何将这个模拟加法器转换为ADD指令,是您有一些逻辑来查看该指令,该指令作为您已安排的这些门的输入。指令中的某些位说这是一条加法指令,有些位说一个操作数就是这样,而该寄存器(可能是寄存器7),其他位可能说另一个操作数是寄存器4。并且取决于您的体系结构可能在指令中定义了另一个寄存器,该指令说将结果存入寄存器2。现在更多的逻辑看到了这一点,因为我需要将寄存器7的内容路由到alu加法器的一个输入,并将寄存器4的输入路由到加法器,然后路由加法器的输出到寄存器2。由于时钟是该逻辑的一部分,因此从时钟周期的开始到下一个时钟周期的开始有一个时间段,所有模拟信号都建立下来并解析它们连接的逻辑方程式。就像您按下电灯开关一样,您可以将灯的状态从关闭状态更改为打开状态。该灯需要一段时间才能预热并基本进入稳定状态。这里没有太大的不同。

有一些逻辑说这样的事情,例如,如果该时钟周期是AND指令的执行阶段,那么下一个时钟周期将把结果保存到输出寄存器中。同时,我将提取下一条指令。因此,对于现代处理器来说,alu执行通常只是一个时钟周期,因为模拟逻辑可以很快地解决逻辑方程。您必须计数的较旧处理器将加法器连接起来,等待x个时钟周期以使加法器逻辑得以解析,然后对输出结果进行采样,将alu输入不同的输入,等待x个时钟周期用于要解决此问题,请永久重复或直到电源关闭。

逻辑方程式是什么意思?就是这样,如果您愿意,可以用AND,OR或NOT Gates来考虑。对于铝加法器电路的每个输入位,都有一个方程式,可能是一个很长的方程式,其中包括时钟,该方程式包括包含当前指令的触发器(单个/单个存储位)(以及分别为每个指令提供输入的方程式)内存位),然后打开。假设您使用的是编写的单个软件功能,该语言要使用您编写的语言,该功能需要输入,执行任务,然后完成并返回结果。考虑所有可能的输入组合,以及该函数的不同执行路径。您可能已经用某种高级语言编写了它,但是甚至可能用那种语言将其重写为使用许多嵌套的if-then-else结构更原始和更加原始的语言。然后深入到汇编语言。就像我在说的方程式一样,当您选择的编程语言节省了大量的代码时,硬件程序员对这些长期方程式的编程要比您可能在汇编语言中的长期if-then-else树中的编程要多。就像您使用的编译器将小的源代码转换为带有许多if-then-eles的冗长程序集一样,有一个编译器将硬件编程语言代码转换为逻辑方程式。

现在回到第一个cpu(今天我们将其视为微控制器,但那时它是cpu)。您在纸上进行了上述所有操作,并且没有使用实际编写逻辑方程式的硬件编程语言,但是您甚至更加谨慎地选择了指令的位模式,以使门的数量和连接这些门的导线变得简单实际可行。在纸上,您必须手工创建一长串连接逻辑门,然后您必须在炸毁的硅掩膜版本上绘制实际组件。即使在今天,也可以使用类似于照相或丝网印刷的外行工艺来完成芯片,因此,如果愿意,您可以拍摄这些蓝图并缩小它们,然后将其应用于硅层。

回到今天,每个人都对汇编有更好的了解,不仅您可能最终要进行一些汇编编程,可能没有文本编辑器或汇编器,也可能不得不手工在纸上编写第一个程序,然后使用参考手册,将其手动转换为机器代码(一和零)。在其中一些计算机上,您可能必须通过以下方式来加载内存:翻转开关,翻转地址位,翻转数据位,直到它们与纸张上的数字匹配,将时钟位向上翻转然后向下翻转,并且您已经用程序的一条指令的一个字节,再重复几百次,希望您不会出错。

就像第一个让我们说C编译器可能是用其他语言编写的方式一样,然后通过用C重新编写并由第一个C编译器进行编译,然后再由其自身进行编译,它就成为了自我托管。然后,使用C编译器来发明其他编程语言,然后这些语言成为自托管语言。我们发明了以自身为基础的操作系统和文本编辑器,而角落里的幕后工作人员则只剩下黑魔法了。

是的,wind之以鼻,这是一个很大的问题,需要多年的学习和经验才能真正掌握。看我的lsasim,我并没有声称自己是任何专家,但是它是一个指令集,既有执行用C语言编写的指令的模拟器,又有可以用硬件编程语言实现的处理器的另一种实现。使用不同的工具进行模拟。再加上一个粗汇编程序和一些其他工具等等。也许,通过检查其中的一些内容,尤其是硬件编程语言代码,可能会缩小我认为您要问的问题。如果我没有缩小差距或切线太长,请让我知道我会很乐意删除此答案(假设我能够在很多程序员交流中不至于闲逛)。


这确实没有回答作者的问题,至少没有在讨论中增加任何内容,接受的答案没有涵盖任何内容。您的二进制数学不是100%正确1 + 1是0与根据注册表的大小为1的溢出它要么是2或0
Ramhound

@dwelch DAMN!我是你的忠贞粉丝。+1
AceofSpades 2012年

2

CPU在0和1上运行。所有指令都有定义它们的位序列。这是机器代码。人类很难读写。第一步,我们将0和1分为4位序列,并使用0到F表示它们。这减少了我们必须记住的数字,但是记住指令的十六进制代码仍然不容易。

因此,我们开始使用具有MOV和ADD之类的“单词”的程序集。汇编程序将用正确的0'和1'集合替换指令,从而将汇编“清单”转换为机器代码。

最终,我们开发了“高级”语言,其中“指令”可以代表整个机器代码序列。


仅供参考,八进制用作十六进制之前的二进制简写。
ocodo 2011年

Slomojo是正确的,八进制,基数8使用3位,十六进制使用基数16,使用4位。Octal的优势在于每个人都知道0到7代表什么数字。人们怎么也没有使用十六进制往往由“数字” A到F迷惑
吉姆ç

0

最近,大约一年前,当我开始沿着这条路旅行时,我遇到了这个问题。对于我自己的相关问题,我会发现这是一个很好的资源和参考页。


第1部分:- 前言-

关于我自己的一点:

在我上小学的80年代中期至后期,我会拆解从50年代到80年代的垃圾立体声音响,VCR和其他电子设备,并且会看着电路板,一直想知道它们是如何做到的。工作...他们实际上是如何获取广播信号,产生音频,视频,执行此操作等的...我可以在这里和那里识别出各个部分,例如电阻器,电容器,二极管和晶体管,但没有了解他们在这么年轻的时候做过什么或如何工作。

多年来,我一直在数学,物理和化学领域表现卓越。我对数学有很高的了解,甚至还可以从中学和高中毕业后读一些简单的或基本的电路,但是我从没学习过逻辑门及其构造方法……但是我做到了从我的逻辑,概率和统计荣誉课程学习高中的布尔代数。我所有的数学和科学课都是荣誉课。直到我在社区学院的第二学期才上微积分。我在大学代数学院进行了测试,并将三角学作为进修课程。我在课堂上的最高数学水平是单个变量的微积分II。

从大约3或4岁起,我就开始玩电子游戏。小时候,我有Atari,NES,Sega Genesis和PS1。随着年龄的增长,进入20年代初期的青少年时代,我获得了带有首选游戏的PS2和SNES。这也不能说明可追溯到《毁灭战士》的PC游戏!

我一直是一个狂热的游戏机和PC游戏玩家,但不包括弹球游戏和街机游戏。

我在90年代初圣诞节时大约12岁时得到了第一台PC。DOS 6.0和Win 3.11或OS / 2的时代。从那时起,我就一直熟悉“ Windows”操作系统家族,而我拥有的所有系统都是Intel体系结构。我在学校或大学期间对Apple或Mac的经验有限,但是我从来没有特权在Linux系统上工作。我确实有Cygwin,并且已经尝试过学习bash,但是我非常习惯于Dos或Command Prompt语法。

在90年代初,我将获得一两本PC-World,并将代码片段输入QBasic,我对此不太了解,并将尝试使这些程序正常工作。唯一成功的是一个程序,可以将主键行上的按键转换为不同的铃声。我不是指手机上的铃声,而是指您按住按键时的连续频率。

我不仅对电子设备如何在数字和逻辑级别上了解电路原理,学习如何对计算机进行编程感到很兴奋,而且我一直渴望制作自己的视频游戏。甚至在90年代初,我就想制作Frogger和Tetris游戏。


这成为我解决计算机科学领域最困难的编程或软件开发类型之一的主要动力和愿望,即3D游戏引擎设计。计算机科学中还有其他领域同样艰难,但是,任何复杂的游戏引擎通常或通常都将几乎包括所有这些引擎,因为单个组件或子引擎需要其技术和/或特性。

我从高中时代起就有编程方面的背景,但这仅限于可怕的Visual Basic。我从2002年至2003年左右开始学习C / C ++,直到1999年我从高中毕业后的几年。直到今天,我还没有任何计算机科学或计算机工程专业的课程经验,但是通过奉献和决心,我已经学会了有关计算机,硬件,编程,算法等的几乎每一个概念,而且我仍然会继续学习尽可能多的知识...

在学习C / C ++的早期,我确实可以访问互联网,但是那时互联网还处于早期阶段,甚至还不存在Amazon,Youtube,Facebook等网站,至今仍是56,000的日子。拨号调制解调器,如果您没有第二条专用线路,则可以拨通电话线。仅需几分钟即可将图像渲染到屏幕上,不必担心连续播放视频。

因此,在研究和学习如何使用C ++编程时,资源是有限的,并且大多数都是文本格式的。在尝试从早期互联网教程时代开始解决这些项目时,其中许多项目尚未完全完成,作家要么是专业人士,要么是大学生,他们做出许多假设,即读者已经熟悉许多所需的概念,例如编译,链接和调试以及库集成。

对于那些对这些主题一无所知的人,他们茫然无措,因为他们不知道出了什么问题,不知道如何解决问题以及如何使其正常工作。在那些日子里,我用非常有限的资源花了很多时间进行反复试验。尚无法寻求诸如我们现在可以在该网站上找到的帮助,或者无法找到可在cppreference上找到的详细说明!如果您个人不认识任何人,那么可以寻求帮助的人就很少!

随着时间的流逝,我确实在各处提高了一些知识,最终互联网改进为DSL,现在是高速互联网,网站变得更具互动性,视频开始出现,视频质量随着时间的推移变得越来越好,随着YouTube的出现,研究方面的事情变得有点容易了。越来越多的教程变得随时可用,有些教程很好而有用,而其他教程则教给了不良做法。

我还花费了大量时间来查找和获取开发所需的工具。我必须学习语言语法,编译器和编译过程,链接,构建和调试。然后,我必须了解那里提供的各种可用的库和API,以及如何配置我的项目或解决方案以链接所有这些依赖项。

多年来,我一直在观察C ++语言随着时间的增长,发展和适应。最初,它多年来一直保持几乎相同,但是在最近的10年中,自成立以来在短时间内就发生了巨大变化。

我之所以提到所有这一切,是因为C ++的多功能性,强大功能,丰富的功能集以及使您步履蹒跚的能力,是最难掌握的语言之一!即使有所有警告,它也是最领先的行业中最强大和首选的语言之一,是此类开发的标准,因为如果正确完成,它将快速,简洁,可靠并使用最小的脚印。

从那时起,我就一直致力于C / C ++的自我教学,并致力于学习3D图形编程和游戏引擎设计。我花了100到1,000个小时的时间进行搜索,研究,并在阅读,学习和应用这些知识到有用的工作产品和应用程序的设计上投入了更多的时间。我一直有意愿和愿望要学习更多以提高自己的技能和手艺。


这是第一步,后来我开始阅读和使用DirectX 9.c,这是在C / C ++甚至C#中完成的。然后我转向DirectX 10和Legacy OpenGL 1.0。从他们那里来的DirectX 11和OpenGL 3.x-4.x,现在我什至在Vulkan尝试了一下。

我建立了成功的游戏引擎,通过各种在线教程(包括文本和视频格式)来工作。我已经说过,我在数学方面有很强的背景,但仅限于微积分I和II。我必须自学向量微积分,我从大学的基于微积分的物理课中学到了一些知识,但是对于具有仿射变换和解析几何的线性代数,我必须自己学习某些方程式,函数,方法,算法和需要概念。然后,我必须学习如何将它们转换为有效的,可读的,可靠的,可重用的代码,这些代码是通用的并且没有错误,并且要花费数百至数千小时的调试时间。

学习包含内存管理,引用计数,实例化,递归等主题和算法的过程非常艰辛,这些主题和算法在庞大的游戏引擎的许多(如果不是全部)组件中使用。我可以在这里列出所有这些信息,但这足以填满3或4个值得写的答案空间。但是,我将包括常规主题列表,而不是其子主题。

以下是包含功能齐全的游戏引擎的主题或主题列表,其中包括所有各种渲染技术,设置渲染和着色器管线,通过着色器的着色和照明技术,预处理和后期处理,帧缓冲区,后缓冲区,图像加载,音频和模型加载与解析,使用色料属性创建原始形状,使用手动纹理映射,对象变换,相机类型,场景图层次结构,纹理,音频,字体和着色器的管理器类创建具有原始材质和法线坐标的原始形状内存管理,具有异常处理功能的日志记录系统,多线程和并行编程技术,网络,物理引擎,碰撞检测,粒子生成器,动画,游戏AI,地形生成,天空盒和天空穹顶,水景渲染,叶子等...,带有纹理字体的GUI用于文本渲染,HUD覆盖,清单,地图和宏生成,状态系统和状态机,最后编写一个解析器来创建自己的脚本语言以自动执行许多此类对象的处理能够在引擎中更改数据值而不必重新编译的能力,只需在应用程序启动时通过加载数据文件以填充其各自容器内的数据对象和结构即可。最后编写一个解析器来创建自己的脚本语言,以自动执行这些对象中的大多数操作,从而能够更改引擎中的数据值,而不必仅通过加载数据文件来填充各自容器中的数据对象和结构即可进行重新编译在应用程序启动时。最后编写一个解析器来创建自己的脚本语言,以自动执行这些对象中的大多数操作,从而能够更改引擎中的数据值,而不必仅通过加载数据文件来填充各自容器中的数据对象和结构即可进行重新编译在应用程序启动时。


多年来,我一直很想学习汇编语言,从他们想了解编译器,汇编器和简单操作系统的过程中,我的意思是指它们的内部工作原理,如何构建和设计它们。

时间流逝,然后我走了几步,开始学习硬件仿真。我专门研究NES,但想学习一般的CPU硬件仿真。这使我开始学习有关指令集的知识,在某种程度上我已经了解了该概念以及它的含义,因为我在某种程度上已经熟悉了英特尔的x86系列,但是现在我必须学习6502指令集。

但是,通过深入研究,我最终进行了更多研究,并开始从工程学的角度学习指令集架构。这使我了解了如何从逻辑门构建CPU,以及如何从晶体管以及其他各种电气组件构建逻辑门。因此,我最终从上至下和自下而上两个角度学习了这一点。两种方法都非常有效,我认为从这两种方法中学习可以帮助建立桥梁或差距,从而在软件中抢占硬件。

由此,我不得不重新学习布尔代数,最终学习了K-映射,蕴涵表,Mealy和Moore的状态机以及将二进制逻辑和算术与物理逻辑门和集成电路相关的各种其他东西。这使我回到过去与Logisim一起工作的怨恨中,开始学习HDL,VHDL,Verilog等。

在过去的15到18年中,我一直在业余时间学习所有这些内容。


这是多年来指导我的一些站点和链接。其中许多都是最近出现的,因为我最初从中了解到的许多网站已经不存在,我丢失了它们的链接并且不记得了,或者搜索引擎将它们推到了他们搜索列表的最后面...

  • 语言-C ++

  • 3D图形教程和资源网站

  • YouTube系列和频道 涵盖了上述主题以及硬件,计算机和电气工程。列出的内容太多了,因此我在这里列出其中一些我认为最有用和最有用的信息。我不会提供链接,但您可以在YouTube上搜索这些频道。

    • 3Blue1Brown- 高等数学
    • Bisqwit- 高级C / C ++编程(应用程序项目)-NES硬件仿真器
    • Jason Turner- 先进的现代C ++编程技术
    • javidx9- 高级C / C ++编程(应用程序项目)-NES硬件仿真器/某些组件
    • 麻省理工学院开放课程 -数学与计算机科学学院课程
    • Bilkent在线课程 -计算机科学与计算机工程学院课程(CPU设计MIPS)
    • Cherno- 高级C / C ++编程主题和应用-游戏引擎开发
    • Ben Eater- 硬件工程-通过面包板的实际应用
    • Neso Academy- 硬件工程-理论与概念
    • Socratica -Python编程
    • 简而言之 -硬件工程-理论与概念
    • 按位 -通过硬件仿真设计高级C / C ++汇编程序
    • Bo Qian- 数据结构和算法中的C ++主题。
    • LineByLine -Vulkan编程
    • Joshua Shucker -Vulkan编程
    • www.MarekKnows.com -C ++,3D数学和游戏引擎开发

而且这些都没有考虑到我所写的有关这些主题的各种书籍。

-注意-请不要对此投票,因为这仅是给读者我个人经验的消息,没有任何尝试回答或引用原始问题的尝试。在接下来的几天里,我有时间。我将添加一个后续答案,以提供有关OP的问题的想法,同时提供有用的链接作为参考和一组资源,并且还将更新此答案,以在此处包括一些链接并修改此注释。已经很晚了,我目前没有时间来校对和编辑我已经写的东西。可以的话,我会做的。”


我刚刚更新了此答案或帖子。我本来要添加第二部分,该部分将实际回答该问题,但是我没有足够的声誉来做到这一点。在我可以添加第二个答案之前,需要花费一些时间来建立所需的信誉点。这篇文章不是实际的答案,但我将使用它作为参考,并在表格中查找真正答案的原因。必须具有上面列出的一些资源,以帮助弥合软件和硬件之间的鸿沟。
弗朗西斯·库格勒

-2

从本质上讲,CPU通常只是状态机。因此,您需要了解逻辑门和触发器或寄存器如何组合以构成状态机。

状态机获取输入和当前状态,通过布尔(以及可能的算术)逻辑运行它们,然后提供输出和下一个状态。输入之一可以是指令寄存器。输出之一可以是启用和选择源以重载指令寄存器,也可以递增或加载用作程序计数器的另一个寄存器。有了它,再加上一些可寻址的存储器,您就可以对指令进行排序。

一旦有了对指令进行排序的方法,就可以使用逻辑将这些指令位以及当前状态解码为另一组控制位。这些控制位中的某些位可以用作控制一组可以执行算术和字宽逻辑的逻辑的输入,称其为ALU。其他位可以加载填充或选择ALU的输入。其他位可以说明将ALU结果存储在何处。或加载寻址寄存器。或写入内存或其他输出。等等。

设计指令集的一部分只是弄清楚哪些位组合在解码时可以控制所有寄存器和状态机排序。这已经完成,并且(重新)优化了数千种不同的方式。

至少有3个级别的大学教科书涉及这个非平凡的主题。


2
这不能解释如何将MOV操作转换为二进制值。这没有提到指令MOV操作是一个值,它是我们使用的关键字,因此我们不必记住16到32位的二进制值。
Ramhound 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.