汇编器和编译器的区别
Difference between Assembler and Compiler
我正在尝试学习 MIPS 汇编语言以更好地理解计算机的工作原理。我通常写 Java 和 JS,我知道 Java 正在使用 编译器 来执行我的代码。当我学习 MIPS 时,我遇到了 assembler.
这个词
How does the way they work differ from each other?
编译器和汇编器都将人类可读的文本转换为特定格式的二进制 object。
区别主要在于:
具体出处方向
在编译器中,细节来自上面,来自它所针对的编程语言。
High-level 语言是 抽象的 ,因为它们在设计时考虑了抽象机器,它们隐藏了硬件细节。
编译器必须将抽象机中的操作映射到目标机(真实机器)中的操作。
在汇编程序中,细节来自下方,来自它所针对的ISA。
汇编是具体(不是100%具体,例如见Pseudo-instructions),它是特定CPU.
的操作码的助记符
汇编程序必须允许程序员像使用操作码一样使用助记符,因为目标是直接指示 CPU,因此在汇编指令和机器指令之间存在紧密的 1:1 映射。
复杂度
High-level 语言的语法很复杂,类似于英语,编译器必须进行的解析和映射非常复杂。
lexer/tokenizer 和 a parser are needed to create an AST 用于相应地生成机器代码,这需要在树的节点之间保持上下文。
我们还期望编译器优化 AST 和生成的代码。
程序集有一个 line-based 语法,词法分析器和解析器一次限制在一行,并且通常可以组合起来并通过智能 table 查找来完成。
没有复杂的状态管理。
实际上没有优化空间,也没有花哨的 hard-to-implement 特征映射到机器码,实际上映射很简单,因为它已经由程序员完成。
Bot 编译器和汇编程序需要支持某些 object 和执行文件格式,因此会出现一些复杂性。
目标
编译器是一种工具,可以实现从用户那里抽象出硬件细节的目标,我们希望编写的源代码在重新编译时可以 运行 理想地用于任何硬件。
汇编器是一种工具,当人们不想抽象化硬件而是想充分利用其功能时,它会派上用场。
因此汇编程序将公开一组 low-level 细节(例如段),而编译器将尝试隐藏这些细节。
我们可以将编译器想象成一个遵循烹饪收据的人,当它说 "mix the milk" 人类必须实际拿起正确的工具(木勺?),将其放入牛奶中,然后进行旋转运动。
这是一件复杂的事情。
汇编器就像一个child,它不会理解"mix the milk"我们必须告诉它"take the wooden spoon from the drawn on the left, it's like a long stick made of wood with a convex end"然后,"Hold the container still with and hand"、"Put the wooden spoon 4-5 inches deep in the milk"、"make a circle, going steady and not too fast, clockwise" , "repeat for 20 seconds".
这些指令更容易解析,同时允许教师更好地控制整个操作,例如如果他们想改变勺子的深度。
那么我们为什么要有汇编程序?
因为我们需要一种方法来精确地生成机器指令,我们可以为此使用编译器,使用特定的语言,但是由于 low-level 指令列表的结构不如一个抽象操作,最终结果将是一个美化的汇编器(或多或少就像拥有像 Git 这样的版本控制软件只是为了提交一个充满 copy-pasted 备份的工作目录)。
所以我们将它们分开:汇编器的简单结构,编译器的复杂语法。
我正在尝试学习 MIPS 汇编语言以更好地理解计算机的工作原理。我通常写 Java 和 JS,我知道 Java 正在使用 编译器 来执行我的代码。当我学习 MIPS 时,我遇到了 assembler.
这个词How does the way they work differ from each other?
编译器和汇编器都将人类可读的文本转换为特定格式的二进制 object。
区别主要在于:
具体出处方向
在编译器中,细节来自上面,来自它所针对的编程语言。
High-level 语言是 抽象的 ,因为它们在设计时考虑了抽象机器,它们隐藏了硬件细节。
编译器必须将抽象机中的操作映射到目标机(真实机器)中的操作。在汇编程序中,细节来自下方,来自它所针对的ISA。
汇编是具体(不是100%具体,例如见Pseudo-instructions),它是特定CPU.
的操作码的助记符 汇编程序必须允许程序员像使用操作码一样使用助记符,因为目标是直接指示 CPU,因此在汇编指令和机器指令之间存在紧密的 1:1 映射。复杂度
High-level 语言的语法很复杂,类似于英语,编译器必须进行的解析和映射非常复杂。
lexer/tokenizer 和 a parser are needed to create an AST 用于相应地生成机器代码,这需要在树的节点之间保持上下文。
我们还期望编译器优化 AST 和生成的代码。程序集有一个 line-based 语法,词法分析器和解析器一次限制在一行,并且通常可以组合起来并通过智能 table 查找来完成。
没有复杂的状态管理。
实际上没有优化空间,也没有花哨的 hard-to-implement 特征映射到机器码,实际上映射很简单,因为它已经由程序员完成。Bot 编译器和汇编程序需要支持某些 object 和执行文件格式,因此会出现一些复杂性。
目标
编译器是一种工具,可以实现从用户那里抽象出硬件细节的目标,我们希望编写的源代码在重新编译时可以 运行 理想地用于任何硬件。汇编器是一种工具,当人们不想抽象化硬件而是想充分利用其功能时,它会派上用场。
因此汇编程序将公开一组 low-level 细节(例如段),而编译器将尝试隐藏这些细节。
我们可以将编译器想象成一个遵循烹饪收据的人,当它说 "mix the milk" 人类必须实际拿起正确的工具(木勺?),将其放入牛奶中,然后进行旋转运动。
这是一件复杂的事情。
汇编器就像一个child,它不会理解"mix the milk"我们必须告诉它"take the wooden spoon from the drawn on the left, it's like a long stick made of wood with a convex end"然后,"Hold the container still with and hand"、"Put the wooden spoon 4-5 inches deep in the milk"、"make a circle, going steady and not too fast, clockwise" , "repeat for 20 seconds".
这些指令更容易解析,同时允许教师更好地控制整个操作,例如如果他们想改变勺子的深度。
那么我们为什么要有汇编程序?
因为我们需要一种方法来精确地生成机器指令,我们可以为此使用编译器,使用特定的语言,但是由于 low-level 指令列表的结构不如一个抽象操作,最终结果将是一个美化的汇编器(或多或少就像拥有像 Git 这样的版本控制软件只是为了提交一个充满 copy-pasted 备份的工作目录)。
所以我们将它们分开:汇编器的简单结构,编译器的复杂语法。