【问题标题】:Difference between: Opcode, byte code, mnemonics, machine code and assembly区别:操作码、字节码、助记符、机器码和汇编
【发布时间】:2013-07-14 02:23:59
【问题描述】:

我对此很陌生。我试图以清晰的方式理解所提到的术语之间的区别,但是,我仍然感到困惑。这是我发现的:

  • 在计算机汇编(或汇编)语言中,助记符是操作的缩写。在每条汇编程序指令的操作码字段中输入。例如AND AC,37,这意味着ANDAC注册到37。所以ANDSUBMUL 是助记符。它们由汇编器翻译。

  • 汇编语言中的指令(语句)通常非常简单,与高级编程语言中的指令(语句)不同。通常,助记符是单个可执行机器语言指令(操作码)的符号名称,并且为每条机器语言指令定义至少一个操作码助记符。每条指令通常由一个操作或操作码加上零个或多个操作数组成。

【问题讨论】:

    标签: assembly


    【解决方案1】:

    OPCODE:这是一个由您的机器(虚拟机或芯片)解释的数字,代表要执行的操作

    BYTECODE:与机器码相同,但主要由基于软件的解释器(如 Java 或 CLR)使用

    MNEMONIC:英文单词 MNEMONIC 的意思是“一种装置,例如帮助记忆某事的字母、想法或联想的模式。”。因此,汇编语言程序员通常使用它来记住机器可以执行的“操作”,例如“ADD”、“MUL”和“MOV”等。这是特定于汇编程序的。

    机器代码:它是打开和关闭计算机中的开关以执行特定工作的数字序列 - 例如数字加法,分支,乘法等。这纯粹是特定于机器的,并且由处理器的实现者详细记录。

    汇编:有两个“汇编” - 一个汇编程序是一系列助记符和操作数,它们被馈送到“汇编器”,后者将助记符和操作数“汇编”成可执行的机器代码。可选地,“链接器”链接程序集并生成可执行文件。

    基于“CLR”的语言(.NET 语言)中的第二个“程序集”是一个注入了元数据信息的 CLR 代码序列,类似于可执行代码库,但不能直接执行。

    【讨论】:

    • Java 不使用“字节码”。 (不是正式的,也就是说。)它只是“代码”。
    • @HotLicks 不完全正确;例如,文档docs.oracle.com/javase/specs/jvms/se5.0/html/VMSpecTOC.doc.html 引用并描述了Java“字节码验证器”。您通常会发现字节码、虚拟机代码(均在上述文档中使用)和其他术语可以互换使用,因为它们本质上是同一个意思。
    • 嗯...我看到“字节码验证器”确实被用作部分标题,并且在该部分中至少使用了两次。但是“字节码”没有出现在索引中,并且该术语没有用于例如类文件格式部分。奇怪的是不一致。
    • @Aniket 我一直在寻找能够说明这些术语之间的进展和关系的东西。无论如何,非常感谢您的帮助!
    • @AhmedTaher 尝试将此要求添加到问题中。另外,我认为以这种方式提供答案会更难,除非您从问题中跳过“字节码”,因为据我所知,这是一个比其他概念更年轻的概念。
    【解决方案2】:

    Aniket 做得很好,但我也要试试。

    首先,了解在最低级别,计算机程序和所有数据都只是数字(有时称为单词),存在于某种形式的内存中。最常见的是这些字是 8 位(1 和 0)的倍数(例如 32 和 64),但不一定,在某些处理器中,每个字要大得多。无论如何,它只是表示为一系列 1 和 0 的数字,或者如果您愿意,也可以是开和关。这些数字的含义取决于正在阅读它们的内容/谁,在处理器的情况下,它一次读取一个单词,并根据它看到的数字(指令)采取一些行动。此类操作可能包括从内存中读取值、将值写入内存、修改已读取的值、跳转到内存中的其他位置以从中读取指令。

    在早期,由于没有键盘、屏幕等,程序员会按字面意思打开和关闭开关来更改内存,打开或关闭灯以读出 1 和 0。随着时间的推移,内存变得越来越大,处理器变得越来越复杂,显示设备和用于输入的键盘被构思出来,由此产生了更简单的编程方式。

    释义 Aniket:

    OPCODE 是指令字的一部分,处理器将其解释为表示要执行的操作,例如读、写、跳转、添加。许多指令也将具有影响指令执行方式的操作数,例如从内存中读取或写入的位置,或跳转到的位置。因此,例如,如果指令的大小为 32 位,则处理器可能使用 8 位作为操作码,并为两个操作数中的每一个使用 12 位。

    从切换开关开始,可以使用称为“监视器”的程序将代码输入机器。程序员会使用简单的命令说出他们想要修改的内存,然后输入 MACHINE CODE 数字,例如以 16(十六进制)为基数,使用 0 到 9 和 A 到 F 表示数字。

    虽然比切换开关好,但输入机器代码仍然很慢且容易出错。更进一步的是汇编代码,它使用更容易记住的助记符代替代表指令的实际数字。 ASSEMBLER 的工作主要是将程序的助记符形式转换为相应的机器码。这使得编程更容易,特别是对于跳转指令,其中指令的一部分是要跳转到的内存地址或要跳过的多个字。用机器码编程需要艰苦的计算来制定正确的指令,如果添加或删除一些代码,可能需要重新计算跳转指令。汇编器为程序员处理这个问题。

    剩下的 BYTECODE 与机器代码基本相同,因为它描述了低级操作,例如读写内存和基本计算。字节码通常被认为是在编译高级语言(例如 PHP 或 Java)时生成的,并且与许多基于硬件的处理器的机器代码不同,它可能具有支持高级语言的特定功能的操作。一个关键的区别是字节码的处理器通常是一个程序,尽管已经创建了处理器来解释一些字节码规范,例如用于 Smalltalk 字节码的称为 SOAR(Smalltalk On A RISC)的处理器。虽然您通常不会调用本机机器代码字节码,但对于某些类型的处理器,例如 CISC 和 EISC(例如 Linn Rekursiv,来自制作唱片播放器的人),处理器本身包含一个解释机器指令的程序,所以有相似之处。

    【讨论】:

    • 非常优雅.....我一直在寻找这样的东西,可以将各个部分联系在一起形成清晰的画面!
    • 我现在正在研究 shellcoding,发现 this 脚本将 shellcode(据我所知现在是执行特定操作的机器代码的十六进制表示)转换为“如所声称的”的二进制文件。这个二进制文件实际上是一个文本文件!二进制这个词如何适合这里的上下文!
    • 严格来说,“二进制文件”这个短语是没有意义和不准确的,尤其是在这里。它通常用于指代具有人类无法有意义解释的内容的文件,例如不使用 ASCII 等字符集。因此,例如,pdf 或 word 文档可以说是二进制格式,因为在查看时我们无法解释内容,而 .txt 文件可以说是文本文件,因为文件中的每个字节直接代表内容。 “可执行二进制文件”是内容代表程序的文件。
    • @naxa "word" 倾向于表示处理器访问的自然内存单元。单词通常是 8 位的倍数,例如32 或 64 位,但所谓的 VLIW(超大指令字)处理器具有更宽的字,例如1024 位,已创建用于并行获取和执行独立指令。但并非所有处理器都使用 8 位的倍数,例如 microchip.com 的微控制器具有 12 位和 14 位指令字。
    • @shadow0359 谢谢。更多的是操作码和操作数一起构成完整指令的一组。没有操作码,操作数没有意义,操作码需要操作数有数据才能操作。操作码本身可能有一些字段,例如用于标识指令类型的组位,例如相对跳转、绝对跳转、加法、减法等,一组标识该指令变体的位,可能还有用于其他目的的位。
    【解决方案3】:

    下面一行是反汇编的 x86 代码。

    68 73 9D 00 01       PUSH 0x01009D73
    

    68操作码。以下字节表示 x86 Assembly 语言的 PUSH instruction。 PUSH 指令将 4 字节(32 位)长度的数据压入堆栈。 PUSH这个词只是一个代表操作码68的助记符。每个字节68739D0001 > 是机器码

    机器码用于真实机器 (CPU),而字节码是用于虚拟机的伪机器码。

    当你写一个java代码时。 java 编译器编译你的代码并生成字节码。 (一个 .class 文件),您可以在任何平台上执行相同的代码而无需更改。

                         JAVA CODE
                             |
                             |
                         BYTE CODE
             ________________|_______________
             |               |               |
          x86 JVM        SPARC JVM        ARM JVM
             |               |               |
             |               |               |
            x86            SPARC            ARM
       MACHINE CODE     MACHINE CODE    MACHINE CODE
    

    【讨论】:

    • 谢谢你 -- 但是为什么 Java 需要生成字节码呢?为什么它不能只创建机器代码(取决于它正在使用的机器)并跳过中间步骤?
    • @Moondra 因为移动性。 Java 的主要座右铭是“一次编写,到处运行”,因此您可以在每个平台上运行相同的可执行文件。否则必须根据 CPU 或操作系统编译代码。
    • @FiratKÜÇÜK 我明白了,谢谢。所以,我假设一些直接编译为机器代码的 C++ 必须有许多针对不同操作系统和 CPU 的子句?
    • @Moondra 是的,平台特定编译必须针对每个平台具有不同的可执行文件。
    • 68 只是 x86 push 可以组装的操作码之一。那是push imm32push register(寄存器编号作为操作码字节的一部分)、push imm8push r/m(通过 modr/m 字节寻址)还有其他操作码。
    【解决方案4】:

    “汇编”起源于非常早期的代码“汇编器”,它可以从多个文件(我们现在称之为“包含”文件)“汇编”程序。 (尽管请注意“文件”通常是卡片组。)使用术语“汇编语言”来指代代码的助记符表示是“汇编程序”的反向格式,并且有些不精确,因为许多“汇编器”不支持包含文件,因此不“汇编”。

    有趣的是,发明“汇编程序”是为了支持“子例程”。最初有“内部”和“外部”子程序。 “内部”子程序就是我们现在所说的“内联”,而“外部”子程序是通过原始的“调用”机制实现的。当时关于“外部”子程序是否是一个好主意存在很多争议。

    “助记符”来源于希腊神Mnemosyne,记忆女神的名字。任何能帮助你记住东西的东西都是“助记器”。

    【讨论】:

    • 作为一个非本地人,他们说“助记器”总是让我感到困惑——因为就非英语外国人而言,“设备”这个词与计算机相关的使用最多感知。我今天的理解是,这个词的选择只是一个不幸的巧合,而“助记器”与计算机无关。 “设备”仅在一般意义上使用,意思是“实现某事或使其更容易做的工具”。
    • @naxa - 英语中的“助记装置”一词至少可以追溯到 40 年,并且可能有 100 年或更长时间。没有什么是“不幸”的——英语中充满了模棱两可的单词和短语,虽然它确实会让非母语人士感到困难,但它使语言更加丰富和富有诗意。
    • 对于一个不战而让混乱接管的人来说是不幸的。语言很优美。
    • 糟糕 - 让“……毫无疑问……”
    【解决方案5】:

    最近我读到了一篇关于这方面的好文章,Difference between Opcode and Bytecode,因此想与对这个话题有很好解释的人分享。 所有功劳归原作者所有

    • 操作码

      操作码是操作码的缩写。顾名思义,操作码是一种告诉机器要做什么的代码,即要执行什么操作。操作码是一种机器语言指令。

    • 字节码

      Bytecode本质上类似于opcode,因为它也告诉机器该做什么。但是,bytecode 并非设计为由处理器直接执行,而是由另一个程序执行。
      它最常用于基于软件的解释器,如 JavaCLR。它们将每个通用机器指令转换成特定机器指令或指令,以便计算机的处理器能够理解。
      事实上,bytecode 这个名称来自指令集,这些指令集具有一字节操作码,后跟可选参数

    【讨论】:

    • 操作码是一种机器语言指令。。不,操作码是每条机器指令的一部分。有些指令只有一个操作码,有些指令有更多位/字节来指定操作数。
    【解决方案6】:
    • 机器码是二进制,但助记符是想法、字母(MOV、ADD 等)
    • 机器码是语言,助记码是汇编语言的一部分

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多