一个有10-20年经验的熟练开发人员,如果从未构建过编译器或模拟器,哪种更具挑战性?
你能比较一下两者可能遇到的障碍。
谢谢。
一个有10-20年经验的熟练开发人员,如果从未构建过编译器或模拟器,哪种更具挑战性?
你能比较一下两者可能遇到的障碍。
谢谢。
仿真和编译是非常不同的,但由于两者都被视为“低级别”,所以往往被混在一起。
仿真一个简单的架构,比如6502或Z80,对于CPU部分来说将是相当简单的,但需要编写大量代码,因为你需要为每个指令编写一个函数。你需要以某种方式自动化这个过程,从指令集规范到所有时序等内容,因为手动输入这些将是非常繁琐的 :) 旧的CPU指令集规范很容易找到,因此在构建仿真器时这有很大的帮助。
除此之外,你还需要实现某种程度的硬件仿真,通常涉及处理和生成中断(例如,如果仿真器是为游戏机而设计,则需要处理和生成显示设备的垂直同步中断)。这又需要一定的规范和代码生成,但你可能需要手工编写大部分代码,因为它不会像指令集代码那样重复(因此无法自动化)。
编译将涉及到将要实现编译器的语言规范和目标输出代码的目标。输出可以是二进制的,也可以是汇编的,甚至可以是另一种语言(这实际上只是一个翻译器,但当目标被认为足够“低级别”时,它也被视为编译)。由于你将在某种硬件或虚拟机平台上运行,因此你不太可能担心中断处理等问题。
两者的难点都是复杂性和正确性-- 对于仿真器,除非你选择非常简单的东西进行仿真,否则你需要使其非常准确。你还需要为仿真器创建某种集成调试器,否则当它无法正常工作时,很难知道出了什么问题。对于编译器来说,将一个玩具语言或更复杂语言的小子集翻译成目标代码应该相对简单,并且可以逐步构建。
请记住,对于这两个项目,您需要能够生成输入以进行测试。如果您无法生成简单的输入,则会发现从一开始就很难进行调试。 仅此一点就使得编译器的工作更容易上手,这是我个人认为的看法 (还有,您可能需要立即拥有一个模拟完整控制台或类似东西的程序 :))
我写过两种方式,我认为模拟器通常更容易。当然,这在很大程度上取决于你想要模拟什么(在iPhone上模拟IBM大型机可能有些困难)以及你想要编译什么(一个小的C编译器相当容易,一个完整的C++编译器几乎是不可能的难度)。
这主要取决于你所模拟的内容以及你所编译的内容。
编写已知模拟平台的仿真器并不难(您也可以使用预制的CPU仿真器,以节省一些开发时间)。
编写未知模拟硬件的仿真器则要困难得多,并将难度转移到与代码开发不同的领域:数学、密码分析、安全协议等。作为开发人员,您必须对涉及到的试错过程有耐心。
例如,想想CPS2仿真所需的时间(CPS2 ROM是加密的)。
如果没有上下文,就没有明确的答案:一切都取决于你想要实现什么,以及你正在面对什么。
如果只是一个“概念验证”,那么在这两种情况下,它都相当简单。
但是,如果您试图模拟具有高精度的复杂硬件或者想要达到AAA编译质量,事情很快就会变得非常复杂。复杂性不仅出现在“主”代码的算法/理论中,还出现在您将不得不构建的所有支持工具中(调试器、反汇编器、分析器等),以便您可以进入下一步。
话虽如此,另一个需要考虑的方面是,为几乎任何编程语言编写工作编译器都具有合理的复杂性。另一方面,如果存在易于模拟的硬件,也有硬件的编写甚至基本仿真器都可能非常复杂。
因此,总体而言,我会说编写编译器更容易,因为您几乎可以保证获得一个工作版本,无论目标硬件或语言如何。对于仿真器则没有这样的保证。
软件仿真相对来说比较简单,但可能会很繁琐。
编写编译器可能非常困难,但如果您对所编写的语言有良好的工作知识或拥有一组良好的规范(例如Backus-Naur形式符号),则可以使其变得更简单。
如果您的目标是使仿真器在许多不同的平台上运行(例如,在MSDOS下使用正确的调整常数可以运行软盘驱动器的定时仿真,但在像Vista或Linux这样的多任务平台上仿真失败),那么硬件仿真可能会非常困难。当关于如何通过软件控制其操作模式的知识不足时,硬件仿真也非常困难。这迫使进行漫长而烦人的逆向工程才能取得进展。
总的来说,我认为仿真更加困难。
编写编译器要困难得多,因为你要处理更低级别的东西(链接、特定于你的架构的汇编语言等)。
模拟器只需要执行输入给它的每个指令的逻辑即可(我知道我在简化这个过程,但我假设你有指令集的规格),现在,编写一个快速的模拟器要困难得多。