高级语言(例如Java)和汇编语言之间的关系

Relationship between High-Level Language (Ex. Java) and Assembly Language?

本文关键字:汇编语言 之间 关系 例如 Java 高级语言      更新时间:2023-10-16

在我的汇编语言书中,虚拟机级别如下所示:

  • 第4级:高级语言
  • 第3级:汇编语言
  • 第2级:指令集体系结构(ISA)
  • 第1级:数字逻辑

根据这本书,2级(ISA)是处理器的指令;ISA也被称为机器语言。该级别中的每条指令都可以直接由计算机硬件执行,也可以由嵌入微处理器芯片中的程序执行,该程序称为微程序

2级以上是汇编语言3级,编程语言提供翻译层,使大规模软件开发变得实用。该级别使用短助记符,如ADD、SUB和MOV,这些助记符可以很容易地转换为级别2的ISA。这些类型的程序在执行之前必须完全翻译或组装成ISA级别的机器语言。

顶层是Level 4,高级编程语言,如C、C++和Java。这些语言包含强大的语句,可转换为多个汇编语言指令。

话虽如此,我并不完全理解高级语言(比如本例中的Java)和汇编语言之间的关系。在我看来,高级语言被简化为单个编程语句可以固有地执行许多代码行的功能,而汇编则需要为每个操作显式语句。

有人能为我澄清一下吗?这是我第一次研究Assembly,到目前为止,它与我在C#中的经历截然不同。

每个程序集语句的高级语句数量变化很大,因此无法很好地衡量两者之间的差异。人们经常会感到有些惊讶,因为实现一个看起来要复杂得多的东西所需的汇编语言语句很少。在某些情况下,汇编语言中的某些东西甚至比高级语言简单得多。

值得注意的主要区别是,在汇编语言中,您可以直接访问CPU的寄存器,这在大多数高级语言中是不可用的。您还负责管理寄存器——决定将哪个变量放入哪个寄存器,将其保存多久,何时将其写回内存,等等

同样,您通常对如何在内存中安排数据有更多的控制权(并承担更多的责任)。在更高级别的语言中,编译器决定在堆栈上创建什么变量,在静态内存中创建什么,在堆上分配什么,等等。在某些情况下(例如,C或C++),您可以对这些决定进行一定程度的间接控制,例如通常在堆栈上分配局部变量,静态分配全局变量。在汇编语言中,此控件是直接和显式的。例如,您不一定要通过名称引用局部变量——您通常会显式引用堆栈指针的偏移量。

还有一点(大部分是次要的):并不是所有的CPU都使用微程序设计。在某些情况下,所有指令都直接在硬件中实现。实现同一指令集的不同型号的CPU之间也可能存在差异——例如,在Intel x86系列中,早期型号(例如808880286)使用微码来执行指令。最近的模型使用的微码lot更少,主要是为了提高执行速度。对于程序员来说,这种变化在很大程度上是无关紧要的,只是微代码指令在当前处理器上执行速度往往相对较慢,所以在大多数新代码中你更有可能避免它们。

高级语言和汇编语言之间没有直接关系。

它可能是C编译器或Java JIT生成汇编语言,然后运行汇编程序将其转换为机器指令。

再说一遍,它可能没有,因为编译器或JIT和汇编程序一样能够输出机器指令

当您编写C编译器或Java JIT时,这完全是一个设计/实现决策。因此,如果你绘制了一张用于在更高级别语言中编译和执行代码的技术图,你可能会完全忽略级别3,这取决于编译器的编写方式。汇编语言主要(并非完全)是一种将机器指令写成人类可读文本的冗长方式,但它并不是生成机器指令的唯一方式(因为机器指令是让CPU做任何涉及"数字逻辑"的事情的唯一方式)。

我不完全确定为什么程序集被列为单独的"虚拟机级别"。与高级语言不同,它与机器指令所做的模型没有明显不同的执行模型。也就是说,它确实抽象了一些机器指令不一定抽象的东西。例如,它包含标签和固定地址等,当机器代码加载到内存并准备运行时,它们会被地址和值所取代。但话说回来,存储在可执行文件中的机器代码也会抽象这些东西,那么这是什么级别呢?也许通过进一步阅读你的书,你会发现这种分级的目的是实现什么。

在过去,有时在今天,编译器和解释器将高级语言翻译成汇编语言。汇编程序将汇编语言转换为机器语言。

概念层与抽象概念、生产力和可移植性有关。高级语言允许程序实现更多的概念,而不用担心寄存器和硬件。从而使程序员的工作效率更高。

高级语言的概念使平台之间的可移植性更加容易。例如,80386程序集中实现的堆栈数据结构不在ARM7上运行。该模块需要为ARM7重写,以便将使用它的任何东西移植到ARM7。

当开发人员在程序集中进行编码时,开发时间会慢到爬行。为了更快地生产产品和项目,需要提高生产力。生产力还包括解决错误的时间。

例如,让我们以语句a = b + c;为例,它是bc之和对变量a的赋值。这涉及以下(通用)低级别操作:

  1. 将变量b的值从内存复制到寄存器0
  2. 将变量c的值从内存复制到寄存器1
  3. 将寄存器0添加到寄存器1,并将和放入寄存器2中
  4. 将寄存器2中的值存储到存储器中的变量a

所以这里的比率是一行高级语言与4行汇编语言。要亲自查看,请使用hello world程序并打印出汇编语言列表。

如果开发人员的错误注入率为每行代码1个错误,那么上面的汇编语言示例将倾向于4个错误,而高级语言则倾向于1个错误。更高级别的语言也被设计来减少程序员在应用程序不断增加时产生的错误。

高级语言的一个缺点是它们能够访问硬件或针对特定处理器进行优化。基本的FORTRAN和LISP,以及Java和C#,都不允许轻松访问硬件。

有比C、C++和Java更高级别的语言。这些语言关注抽象概念和实现,使程序员能够更多地关注概念而不是语言。

首先,每种高级语言都有自己的执行程序的方式(有些类似)。

Java程序编译成Java字节码,然后在模拟器(它自己的虚拟计算机)中执行。在执行过程中,该模拟器(从外部)与操作系统通信,并使用其操作系统调用。对于示例:您有一个用Java实现的文件资源管理器。当代码中删除文件的部分正在执行时,会向操作系统发送一条消息进行删除。

尽管如此,高级语言的主要思想是可以使用的抽象(如果你想为数据库实现查询,你并不真正关心汇编级的优化)。

历史:第一台计算机(当然是电动计算机)只用汇编语言编程。为什么会发生这种情况,为什么没有直接用Java编程?因为它需要一个从Java语言到硬件知道的语言的翻译器,而这个翻译器(事实上,或多或少就是编译器)占用了大量的内存,而且当时可能不可能为每个程序执行。

很容易想到"for"循环语句,但不可能实现每次使用循环时执行的翻译器。

硬件发展之后,编译器得以实现,高级语言得以创建。

所以,你想要掌握的这种关系实际上只是计算机历史上编程语言的不断发展。

我认为答案是:只有当你考虑机器代码=汇编代码时。高级语言基本上是编译或解释的。在第一种情况下,高级语言被翻译成一组机器代码指令,这取决于体系结构的类型。然而,在大多数情况下,汇编代码和机器代码之间存在1:1的对应关系,但这并不总是正确的(我建议您阅读本讨论汇编代码与机器代码与对象代码?)。

在第二种情况下,被解释的语言被翻译成中间语言,然后由解释器直接执行,跳过机器代码翻译。因此,在这种情况下,不会生成任何程序集代码。