编译器作者实际上是否需要“理解”机器代码?[关闭]


10

可能是一个奇怪的问题。

一个编写C ++编译器(或任何非VM语言)的人:是否需要能够读写原始机器语言?这是如何运作的?

编辑:我专门指的是编译为机器代码的编译器,而不是其他某种编程语言。



1
不,您甚至不需要了解它,您可以盲目地,漫不经心地复制目标ISA规范:dl.acm.org/citation.cfm?id=1706346
SK-logic

1
Coffescript 编译为javascript。
卡蒂克2014年

@Kartik可编译为Javascript的CoffeeScript编译器是否还包括可编译为任何Javascript的Javascript编译器?还是仅编译为Javascript源代码而已?
Aviv Cohn 2014年

coffeescript编译器仅将cofeescript转换为javascript。Javascript未编译,由浏览器处理。我想说的是,您可以编写将一种语言编译为另一种语言的编译器,而您不必了解机器语言。另一个示例是“ SPL”编译器,该编译器将莎士比亚的剧本编译为C ++。shakespearelang.sourceforge.net
Kartik

Answers:


15

一点都不。编译器完全有可能(甚至通常更可取)发出汇编代码。然后,汇编器负责创建实际的机器代码。

顺便说一句,区分非VM实现与VM实现是没有用的。

  • 对于初学者来说,使用VM或对机器代码进行预编译只是实现一种语言的不同方式。在大多数情况下,可以使用任何一种策略来实现一种语言。实际上,我不得不使用一次C ++ 解释器

  • 同样,像JVM这样的许多VM都具有二进制机器代码和一些汇编程序,就像普通的体系结构一样。

LLVM(由Clang编译器使用)在这里值得特别提及:它定义了一个VM,其指令可以表示为字节码,文本汇编或数据结构,这样可以很容易地从编译器发出指令。因此,尽管它对于调试(了解您的工作)很有用,但您甚至不必了解汇编语言,而只需了解LLVM API。

LLVM的好处是它的VM只是一个抽象,字节码通常不被解释,而是透明地JITted。因此,完全有可能编写一种经过有效编译的语言,而无需了解您的CPU指令集。


LLVM的另一个不错的特性是,无需深入了解目标ISA即可实现高效的后端。它是声明性的,因此几乎可以将ISA规范复制并粘贴到.td文件中,而无需尝试理解它。
SK-logic

谢谢回答。问题:我从您的回答和其他回答中了解到,编译器编写人员不必了解机器代码,他可以使用其他工具为他执行实际的转换为机器代码。但是,编写该工具的必须懂机器语言,对吗?编写将某种语言实际转换为机器代码的软件的人必须真正理解机器语言,对吗?
阿维夫·科恩

5
@Prog是的。如果创建抽象层,则只需了解您下面的层。基本了解所有层很有用,但这并不是必须的。您无需了解量子物理学即可使用晶体管。您无需了解芯片设计即可使用CPU。您不需要知道机器代码即可编写汇编。使用VM等时,您不需要了解平台的指令集。但是,有人必须在您的平台之下构建这些抽象级别。
2014年

1
@ SK-logic从我所听到的来看,不是真的(至少如果您想要好的代码)。为llvm实现Aarch64后端的人们面临很多挑战(其中一个重定位,负载存储模式可怕,..)。这就是忽略在房间里的大象最大:该ISA的内存模型和语言,你的内存模型有兴趣你可以在编译器的工作,但你可以不理解架构上后端不会工作。。
Voo 2014年

1
从概念上讲,我想补充一下,汇编代码和机器代码之间确实没有实质性区别。一旦知道如何使用特定指令,该指令的操作码是什么,您将不会真正受益。如果您知道如何使用MOV,则不知道它是指令27还是没有关系的,我认为它类似于@ SK-logic所描述的内容。
whatsisname 2014年

9

否。您的问题的关键是编译是一个极为广泛的术语。编译可以从任何一种语言转换为任何一种语言。汇编/机器代码只是众多编译目标语言之一。例如,Java和.NET语言(例如C#,F#和VB.NET)都编译为某种中间代码,而不是机器特定的代码。然后是否可以在VM上运行都无关紧要,该语言仍会编译。还可以选择编译为其他语言,例如C。C实际上是非常流行的编译目标,许多工具都可以实现。最后,您可以使用一些工具或库来完成为您生成机器代码的艰苦工作。例如,LLVM可以减少创建独立编译器所需的工作。

另外,您的编辑没有任何意义。这就像在问“每个工程师都需要了解发动机的工作原理吗?我是在问工程师在发动机上工作。” 如果您正在处理发出机器代码的程序或库,那么您必须了解它。关键是,在编写编译器时不必执行此类操作。许多人在您之前完成了此操作,因此您需要有充分的理由再次执行此操作。


而编写实际转换为机器语言的工具或库的人,是否必须完全理解机器语言,对吗?
阿维夫·科恩

3
@Prog是否需要完全了解一种编程语言才能进行编程?不,但是您可能会编写次优的代码,并且您无法做其他人可能做的某些事情。如果编写翻译成机器语言的编译器,您是否需要完全理解机器语言。否,但是您的编译器将不是最佳选择,并且无法执行某些操作。
Sumurai14年

@ Sumurai8:尽管在某种程度上您可以分段地“理解”机器语言,以便编写一个比您更了解整个事物的机器代码发射器。例如,如果您编写了一个好的框架,则可以配置每个操作码的定义及其成本和流水线注意事项,然后,即使您没有专门知识来优化该特定机器,框架也可以编写优化的机器代码。自己能够熟练地编程该机器代码可能不会受到伤害。
史蒂夫·杰索普

@SteveJessop如果您了解每个操作码的程度,可以学习一台机器如何将该操作码与其他操作码链接在一起以表达更高层次的概念,那么您确实可以完全理解机器语言。然后,您就懒得为那里的每个问题找到最佳解决方案;-)
Sumurai8 2014年

@ Sumurai8:嗯,但是至少从原则上讲,我可能会在五分钟的配置过程中短暂地“理解”每个操作码,然后在接下来的“理解”操作码之前就已经忘记了它。发问者可能不是“能够读/写原始机器语言”的意思。当然,我在这里假设一个相当不错的框架,该框架可配置为足以定义和使用有关指令集每个操作码的所有有用信息。LLVM对此有所针对,但是据“ Voo”(在下面的评论中)并没有实现。
史蒂夫·杰索普

3

传统上,编译器包含三个部分:词法分析,解析和代码生成。词法分析将程序的文本分为语言关键字,名称和值。解析会分析来自词法分析的标记如何在语言的语法正确声明中进行组合。代码生成采用解析器生成的数据结构,并将其转换为机器代码或其他某种表示形式。如今,词法分析和解析可以合并为一个步骤。

显然,编写代码生成器的人员必须非常深入地了解目标机器代码,包括指令集,处理器管线和缓存行为。否则,编译器生成的程序将很慢且效率低下。他们很可能能够读写以八进制或十六进制数字表示的机器代码,但是它们通常会编写函数来生成机器代码,并在内部引用机器指令表。从理论上讲,编写词法分析器和解析器的人可能对机器代码的生成一无所知。实际上,某些现代编译器允许您插入自己的代码生成例程,这些例程可能会为词法分析器和解析器编写器从未听说过的某些CPU发出机器代码。

但是,实际上,编译器作者在每个步骤中对不同的处理器体系结构都了解很多,这有助于他们设计代码生成步骤所需的数据结构。


2

很久以前,我编写了一个在两个不同的Shell脚本之间转换的编译器。它离机器代码没有任何距离。

编译器编写人员必须了解其输出,但这通常不是机器代码。

大多数程序员永远不会编写输出机器代码或汇编代码的编译器,但是自定义编译器在许多项目上非常有用,可以产生其他输出。

YACC就是这样一种编译器,它不输出机器代码。


0

你不需要启动你的输入和输出语言的语义的详细知识,但是你最好完成与两者的一个精美的详细知识,否则你的编译器会unusably马车。因此,如果您的输入是C ++,而您的输出是某些特定的机器语言,那么您最终将需要了解两者的语义。

以下是将C ++编译为机器代码的一些细微之处:(就在我的头上,我确定还有很多我忘记的地方。)

  1. 大小int是多少?基于机器的自然指针大小,各种算术运算大小的ALU的性能以及现有编译器为机器所做的选择,此处的“正确”选择是一门艺术。机器是否甚至具有64位算术?如果不是这样,则将32位整数相加应转换为一条指令,而将64位整数相加应转换为进行64位加法的函数调用。机器是否具有8位和16位加法运算,或者您必须模拟具有32位运算和掩码的运算(例如DEC Alpha 21064)?

  2. 机器上其他编译器,库和语言使用的调用约定是什么?参数是从右到左还是从左到右被压入堆栈?有些参数进入寄存器,而其他参数进入堆栈吗?整数和浮点数是否位于不同的寄存器空间中?寄存器分配的参数是否需要在varargs调用中进行特殊处理?哪些寄存器保存了呼叫者,哪些保存了被呼叫者?您可以执行叶子调用优化吗?

  3. 机器的每个换档指令有什么作用?如果您要求将64位整数移位65位,结果是什么?(在许多机器上,结果与移位1位相同,在其他机器上,结果为“ 0”。)

  4. 机器的内存一致性语义是什么?C ++ 11具有定义非常明确的内存语义,在某些情况下对某些优化设置了限制,但在其他情况下允许进行优化。如果您正在编译一种没有明确定义的内存语义的语言(例如C ++ 11之前的每个版本的C / C ++以及许多其他命令式语言),那么您将必须不断学习内存语义,并且通常您将需要发明与您的机器语义最匹配的内存语义。

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.