【问题标题】:Small RISC emulator小型RISC模拟器
【发布时间】:2010-09-20 22:03:42
【问题描述】:

我正在寻找将 VM 构建到游戏中,并且想知道是否有人知道任何非常简单的 VM(我认为 RISC/PIC 与我想要的很接近)通常用于嵌入式项目,例如控制机器人、电机、传感器等。如果我自己动手,我主要关心的是必须编写一个编译器/汇编器。我会很高兴使用已经存在的工具,或者以最简单的形式使用可以为其编译的 C 编译器:-p。

我真的不想在这里重新发明轮子,但我还需要在虚拟世界中运行数千个这样的设备,因此它们必须尽可能简单和快速。正如一个人已经提到的那样,我也不关心现实世界的问题,例如时间和公共汽车以及所有有趣的东西。我认为他们的虚拟时钟将仅限于非常慢的东西。最终我可能不得不研究原生编译以使它们运行得更快,但现在我只是将原型放在一起以获得一般的概念证明。

作为输入,我计划安装在圆柱体周围的距离、光线、材料和触摸传感器(16 个,也许是 32 个),然后只需 2 个电机用于定向输出,以控制每侧的一种轮子。基本上处理不会太费力,世界会很简单,以至于机器不必在简单的任务上投入大量的处理能力。

在内存方面,我希望他们能够存储足够的数据,以便在不干预构建地图和收集统计数据的情况下单独放置几天。我不喜欢 8bit 会因为处理或内存而减少它,但 16bit 肯定会是一个竞争者。 32 位和 64 位只会推动它,而且它们的每个内存不可能超过 1mb - 可能更接近 256-512k。 (比尔一说 640k 就足够了,为什么我不能!!)

【问题讨论】:

    标签: embedded emulation cpu-architecture embedded-language


    【解决方案1】:

    我为一位朋友写了Wren,他希望在具有大约 16K RAM 的嵌入式控制器上运行 VM 语言。 (但它允许在编写的代码中每个进程最多 64k。)它包括一个用于愚蠢的小编程语言的编译器。这一切,呃,非常基本,并没有看到太多用处,但这正是您在第一段中描述的内容。

    【讨论】:

    • 嗯...需要文档。我对自我链接持怀疑态度,但这似乎反应灵敏。点赞。
    【解决方案2】:

    FORTH“虚拟机”就这么简单。 16 位地址空间(通常)、16 位数据字、两个堆栈、内存。 Loeliger 的“Threaded Interpretive Languages”告诉你很多关于如何在 Z80 上构建 FORTH 解释器的信息。

    【讨论】:

      【解决方案3】:

      如果您想要一些植根于现实世界的东西,最常用的嵌入式 RISC 微控制器之一就是 PIC 系列。 google 提供了几个模拟器,但我不认为大多数人都可以使用源代码。

      另一种可能性是 QEMU,它已经模拟了几个 ARM 品种。

      当然,如果您对模拟真实世界的设备不感兴趣,那么自己动手做会更容易,性能更好。只包含您需要的东西,而不是陷入状态标志、溢出位、有限总线宽度、RAM 时序等的混乱中。

      【讨论】:

      • 是的。我可以看到我想要它做的所有事情,就像你说的时间和标志以及所有现实世界的废话都不必存在 - 我想补充的主要问题是我想有一个编译器准备好为它构建;-p
      • 那么不要模拟 CPU,而是使用嵌入式脚本语言。 Lua 是一门漂亮的语言,从一开始就被设计为作为 C 应用程序的扩展嵌入
      • 我对 lua 真的很感兴趣,但我只是没有理解它的语法,以至于真的想用它做更多的事情。
      【解决方案4】:

      如果您想要简单,请考虑 Manchester Mark I。请参阅this PDF 的第 15 页。机器有7条指令。为它写一个解释器大约需要一个小时。不幸的是,说明非常有限(这就是为什么机器的完整规格几乎可以放在一页上)。

      Javier 自己动手的方法非常务实。如果是这样的话,设计和制造一台微型机器是一项两天的任务。几年前我为一个项目构建了一个微型 VM,我花了两天时间用一个简单的可视化调试器编写了这个 VM。

      另外 - 它必须是 RISC 吗?例如,您可以选择 68K,其中有 open source emulators,而 68K 是 gcc 的一个众所周知的目标。

      【讨论】:

      • 我完全不担心自己构建 - 我只是不想急于编写编译器。如果我可以将它尽可能接近其他也有 c 编译器的东西,那么它应该会容易得多。
      • 我也不是 100% 相信它会使用基于文本的编程,但现在它也更容易了:-p
      • 在这种情况下,我肯定会选择 68K(首选)或 6809(oddchange.com/gcc6809)。两者都是 gcc 目标并且是相当友好的 CPU。 MAME 包含两者的模拟器。 6809 将您限制在 64K 的地址空间内,而无需欺骗。
      【解决方案5】:

      许多编写游戏程序和其他应用程序的人在应用程序中嵌入了一种语言,以允许用户编写小程序。

      据我所知,最流行的embedded languages 大概是最流行的第一顺序(尽管“更流行”并不一定意味着“更好”)似乎是:

      • 专为这一特定应用程序定制的领域特定语言,其他任何地方都没有使用
      • 卢阿a
      • Tcl
      • Python a b,通常是简化的子集,例如 PyMite c
      • 第四次
      • JavaScript a
      • Lisp
      • AngelScript a
      • XPL0 a b
      • 松鼠a
      • Haskell a b
      • NPCI(纳米伪 C 解释)a
      • RoboTalk
      • 解释一些硬件机器语言(为什么这是最不受欢迎的选择?有充分的理由,如下所述)。

      您可能想查看 Gamedev StackExchange,特别是像 "How do you add a scripting language to a game?" 这样的问题。

      您可能想在 StackOverflow 上查看标记为 "embedded language" 的一些问题; 如 "Selecting An Embedded Language", "What is a good embeddable language I can use for scripting inside my software?" "Alternatives to Lua as an embedded language?" "Which game scripting language is better to use: Lua or Python?", 等等

      这些语言的许多实现都使用某种 bytecode 内部。 通常,同一高级编程语言(如 JavaScript)的两种不同实现在内部使用两种完全不同的字节码语言(a)。 通常几种高级编程语言编译成相同的底层字节码语言——例如,Python 的 Jython 实现、JavaScript 的 Rhino 实现、Tcl 的 Jacl 实现、JScheme 和 Scheme 的其他几种实现,以及 Pascal 的几种实现;都编译成相同的 JVM 字节码。

      详情

      为什么要使用脚本语言而不是解释某些硬件机器语言?

      为什么是"Alternate Hard And Soft Layers"? 为了获得简单性和更快的开发。

      更快的开发

      人们通常使用脚本语言而不是编译语言来更快地工作。

      让初始原型工作通常要快得多——解释器会处理一堆机器语言强制你显式写出的幕后东西:将变量的初始值设置为零、子程序序言和子程序-epilog 代码、malloc 和 realloc 以及 free 和相关的内存管理东西,当容器满时增加容器的大小,等等。

      一旦有了初始原型,添加新功能就会更快:脚本语言具有快速的编辑-执行-调试周期,因为它们避免了编译语言的编辑-编译-执行-调试周期的“编译”阶段。

      简单

      我们希望嵌入式语言在两个方面“简单”:

      • 如果用户想编写一个小代码来完成一些概念上微不足道的任务,我们不想用复杂的语言吓跑这个人,需要 20 磅的书和几个月的学习才能编写没有缓冲区溢出的“Hello, $USER”。

      • 由于我们正在实现该语言,我们想要一些易于实现的东西。也许一些简单的底层指令我们可以在一个周末敲出一个简单的解释器,也许我们可以通过最少的调整来重用某种预先存在的编译器。

      当人们构建 CPU 时,硬件限制总是会限制指令集。 许多概念上“简单”的操作——人们一直在使用的东西—— 最终需要大量机器语言指令来实现。

      嵌入式语言没有这些硬件限制,允许我们实现 更复杂的“指令”执行(对人类而言)在概念上看起来很简单的事情。 这通常会使系统在上述两种方面变得更简单:

      • 直接使用该语言编写代码的人(或为该语言编写编译器的人)最终编写的代码要少得多,单步调试代码所花费的时间也更少,等等。

      • 对于每个这样的高级操作,我们将复杂性从编译器转移到解释器内的指令实现。与其(您编写代码)编译器将一些更高级别的操作分解为中间语言中的一个短循环(并在运行时在解释器中反复单步执行该循环),不如编译器以中间语言发出一条指令(并且您在解释器对该中间“指令”的实现中编写相同的一系列操作)。使用编译语言(“内部”复杂指令)实现所有 CPU 密集型的东西,极其简单的解释器通常足够快。 (即,您避免花费大量时间构建 JIT 或尝试以其他方式加快速度)。

      由于这些原因和其他原因,许多游戏程序员使用“脚本”语言作为他们的“嵌入式语言”。

      (我现在看到 Javier 已经建议“使用嵌入式脚本语言”, 所以这变成了对为什么这是解释硬件机器语言的一个很好的替代方案,并在一种特定的脚本语言似乎不适合时指出替代方案的长篇大论。

      【讨论】:

        猜你喜欢
        • 2018-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-02
        • 2015-06-22
        • 2011-11-08
        • 2014-09-30
        相关资源
        最近更新 更多