除了二进制本身就是二进制(十进制表示法等)之外,二进制序列仍然需要编程为mean&启动某些任务。话虽如此;更具体/澄清:
如何实现自定义汇编语言自定义助记符从头开始,定义值&定义让二进制程序在特定地址寄存器执行特定任务?(即将键盘键等映射到汇编语言、汇编程序等)。(用于在64位计算机上实现)。
简而言之,我在询问从二进制开始的问题。本质上是最低级别的操作。定制CPU/GPU对于这种实现是必要的吗?
所以你问汇编语言,它只是一种低级编程语言,通常旨在与特定的指令集架构(ISA或指令集)有直接关系。如果你问你是否可以为现有的ISA编写一个新的指令集,那么绝对没有什么能阻止你这样做,而不是像一样
mov ax,[bx]
你可以制作
ldr ax,[bx]
或
lw ax,(bx)
或
bob pickle,(pencil)
这是您的选择,然后简单地编写一个解析器并生成指令
完成。
如果问题是从头开始创建一个新的指令集,那么Erik几乎涵盖了这一点,然后从一种或多种汇编语言开始。
你首先需要创建指令集,老实说,由于你问的问题,你既不熟悉指令集,也不熟悉汇编语言。因此,今天我们的优势是能够检查许多指令集和汇编语言,并对它们感到满意。同样,如果你想建造一栋房子,这不是穴居人时代,你不必从头开始,有数百万/数十亿的房子可以看,不仅仅是墙壁和屋顶的基础,我喜欢前面还是后面的车库,或者没有,一层还是多层。地下室等。这里也是,我喜欢指令集什么,我不喜欢什么。想要创建一个新的指令集,需要有一个强有力的理由,这样你就必须有你不喜欢的东西,或者一些商业或教育原因,这意味着你有你想要修复或实现的细节,而其他指令集没有,或者一个有,另一个没有,你想找到一个中间立场。
让我们暂时忘记专利,因为它会干扰任何真正的实施。
你必须决定固定长度或可变长度,但早在你到达这里之前,你就已经有了许多指令集的经验,你已经在脑海中思考了为什么你试图创建一个新的指令集,而不是仅仅使用一个,或者制作一个克隆(再次忘记了法律问题)。
对于通用处理器,您需要一些基本的alu操作add、sub、and、xor等。您需要一些基础的加载和存储指令。某种形式的无条件和条件分支,等等
你是在做一个基于堆栈的处理器还是普通风格的处理器?
如果在开始之前,你想使用可变长度,那么你仍然需要一个最小大小,所以可能像x86一样,你想要8位指令,而该操作码要么是整个指令,要么描述需要更多字节。或者,你可能想要16位,但仍然允许可变长度,或者使用固定长度,这可能意味着32位或64位,但你可以通过arm、mips、risc-v和其他可能的方式看到,你可以有16位指令和32位(或更大)指令,并通过某种方案在它们之间切换。
然后你把编码搞出来。与pc相关的东西,你可能想要有很多直接位,位越多,它可以达到的长度就越长,假设指令长度固定,如果长度可变,那么你仍然必须决定是否有限制,或者在编码中选择偏移大小的方案。如果已修复,则需要一种方法来指示哪些位覆盖这些大型立即编码。
因此,虽然ARM的编码对那些在MIPS上咬紧牙关的人来说似乎很混乱,但你可以回到Acorn图,甚至ARM的部分,看到它一点也不混乱,从最高位开始,想要更多直接位的指令可以用更少的位来确定,则它们将另一个比特和另一个位添加到编码中,从而形成唯一的起始比特并通过需要较少比特的指令来确定指令。例如指令集的1/4专用于一种类型的指令,然后1/8专用于另一种类型,1/16的可能编码另一种风格,等等。另一种方法是mips,比如你保留一些位作为操作码位(然后对于一些操作码,其他位作为扩展操作码位使用),但总体上受到任何指令的限制,但解码要容易得多,这是一种折衷。
你可以像CISC一样,假设一个微编码的体系结构,一个简单的8位操作码,其中的位不表示任何东西,它们只是形成一个唯一的数字,在表中查找以确定它的作用。你可以查看visual6502页面和那一代的指令集,操作码基本上是rom中的一个地址,rom包含实现该指令的步骤的微码。
你可以选择一个vliw指令集,它有点像公开的微码,你可以用控制信号和寄存器文件地址来封装它。然后拥有比RISC解码和执行更简单的状态机。
你还有很多其他的基本指令集问题——有寄存器还是基于堆栈,有一个寄存器,两个还是8个,16个还是256个。您的寻址模式是什么,处理器总线是什么样子的,等等。
最终,你开始适应指令集。自然地,当你开发这一功能时,你会在脑海中或写下指令的名称,这一功能使用寄存器内容作为地址从内存加载。这个增加了两件事。这个将一个寄存器内容复制到另一个寄存器。因此,作为跟踪自己或与他人交流的一部分,你有这些术语,而你的汇编语言可能就是来自这些术语。然后你进入它是副本还是移动,你拼写它是mov还是move。你用mov还是load-and-store?你拼写它们ld、load、ldr等吗?你喜欢目的地在前,喜欢目的地最后吗。你有立即数/常量吗(添加寄存器7=寄存器3+5)如果有,你需要一个解析标记来指示这些吗?你默认使用十进制、十六进制、八进制或二进制作为语法中值的编码吗。
所以你开发了一种汇编语言,然后想要开发一种工具。你是用蛮力还是用野牛/柔性的东西?还是其他解决方案?
您是否允许汇编程序使用类似.org的语句生成完整的二进制文件,或者您是否同时或仅强制对象,然后必须创建一个链接器将对象链接到二进制文件中?如果你这样做了,那么你就可以创建其他语言,以后也可以这样做。
在深入实现之前,您希望汇编程序至少非常快,这样您就可以在不必测试处理器的情况下进行工作手动代码太多的机器代码。
现在和过去都有一些指令集,比如tty指令和其他触及处理器中特定外围设备的指令。但通常情况下,外围设备被映射到总线(I/O总线或内存总线或其组合)上的某个地址,指令集并不在意,从长远来看,它提供了更灵活的功能,可以随着世界的发展添加或删除外围设备,而无需更改指令集。您可能不希望将一般外围设备集成到指令集中。
现在,gpu通常是一个完全独立的指令集,经过相同的过程,但目标更多地针对特定的应用程序而不是通用处理器进行调整。但是,将它们结合起来当然是可能的。有一个既具有通用处理功能又具有图形处理功能的指令集。你可能会发现,你可以找到一种让它运行良好的方法,但这通常没有帮助,gpu进化为从主处理器上卸载工作,这样主处理器就可以尽可能努力地工作,并将特定的工作传递给gpu。请给我画一个正方形,而不是这里是我必须一次计算一个的4000像素。
然后您需要编译器,然后是操作系统、应用程序,然后是客户。正如你所看到的,比如wintel与linux在arm上的对比,一个对用户来说和另一个一样有用,它消耗的功率要高得多,等等。但由于非技术性的原因,你很难打破现有世界的势头。
所以,归根结底,你问这个问题意味着你还没有准备好开始这样的任务,你需要学习至少十几个指令集及其汇编语言,最好是来自历史上不同时期的不同公司。pdp8、pdp11、6502、8051、68K、x86、arm、risc-v、PIC、msp430、avr-mips、powerpc、sparc,仅举几个例子。可能还有其他一些,比如amd2900和基于堆栈的zpu是什么?或者可以这样做,看看gnu支持的每一个指令集和llvm支持的所有指令集。你会保留应该在你的清单上的pdp11,但会失去pdp8和6502,它们有一些独特的功能,在最初的检查中可能很明显,也可能不明显,但值得知道,让你保持清醒。然后,对于gpu方面,只需研究一些gpu,树莓派中的gpu现在已经有了一些记录,毫无疑问还有其他gpu。
如果你对此很认真,并且正在考虑一种可以与当前产品竞争的产品,你需要愿意为第一个芯片/处理器投资数千万至数亿美元。这可能会让你得到在单ghz范围内运行的东西。如果你想进入下一阶段,将其乘以4可能是2ghz以上。当然,你可以构建一个简单的小东西,它几乎什么都不做(没有指令集),但用更少的钱运行得很快,但你要的是一个带gpu的64位处理器。
你需要知道的一切都可以在网上免费找到。你只需要通过指令集、hdl语言、免费和严肃的hdl工具、廉价和不便宜的sim解决方案的教育过程。在世界上芯片工程师人数占一定比例的地区,由于这是一项过山车般的业务,x公司正在制造一种新芯片,在几年内吸纳50-100人,然后解雇他们。y公司正在制造新芯片,吸纳5-100人,然后裁掉他们。重复如果你愿意,你可以成为z公司。
为了编写自己的(汇编或任何)语言,您需要考虑以下几点。
- 少数变量(可以被视为一类一元函数)和函数是常量:它们由您使用的CPU(例如,RAX、mov)和您使用的操作系统(例如,来自Windows、GNU Linux、*BSD的中断)定义。它们是常数,因为你不能选择它们,它们与你选择的目标系统绑定在一起
- 您想要使用的语言(即语法-语义对的函数)
- 重写系统,它将使您的语言转换为系统常量。可以将其视为一个函数生成器/减少器/规范化器
进行此类翻译的一种基本方法是使用汇编宏,这也是函数,也是重写规则。
命令.macro
和.endm
允许您定义生成程序集输出的宏。例如,这个定义指定了一个将一系列数字放入内存的宏和:
.macro sum from=0, to=5
.long from
.if to-from
sum "(from+1)",to
.endif
.endm
有了这个定义,SUM 0,5
就相当于这个汇编输入:
.long 0
.long 1
.long 2
.long 3
.long 4
.long 5
(来自sourceware.org)
我认为,这个项目最重要的部分是设计一个(语言及其)重写系统,它将具有良好的性质,即,它必须终止,它必须融合,它必须规范。重写规则可以通过汇编宏来定义。