汇编代码vs机器代码vs目标代码?


227

目标代码,机器代码和汇编代码之间有什么区别?

您可以举一个直观的例子说明它们的区别吗?


我也很好奇“目标代码”名称从何而来?“对象”一词在其中应该意味着什么?它以某种方式与面向对象的编程有关还是只是名称的巧合?
SasQ '16


我不是在问什么是目标代码,上尉船长。我在问这个名字是从哪里来的,为什么叫“对象”代码。
BarbaraKwarc

Answers:


296

机器代码是二进制代码(1和0),可以直接由CPU执行。如果要在文本编辑器中打开机器代码文件,则会看到垃圾,包括不可打印的字符(不,不是那些不可打印的字符;))。

目标代码是机器代码中尚未链接到完整程序中的一部分。构成完整产品的特定库或模块的机器代码。它还可能包含在完整程序的机器代码中找不到的占位符或偏移量。该连接器将使用这些占位符和偏移连接一切融合在一起。

汇编代码是纯文本格式的(并且是人类可以读取的)源代码,其中大多数具有与机器指令的直接1:1模拟。这可以通过使用助记符来实现实际的指令,寄存器或其他资源来完成。示例包括JMPMULT用于CPU的跳转和乘法指令。与机器代码不同,CPU不理解汇编代码。您可以使用汇编器编译器将汇编代码转换为机器,尽管我们通常认为编译器与从CPU指令进一步抽象的高级编程语言相关。

构建完整的程序需要用汇编语言或更高级别的语言(如C ++)编写该程序的源代码。源代码被汇编(用于汇编代码)或编译(用于高级语言)为目标代码,并且各个模块链接在一起,成为最终程序的机器代码。对于非常简单的程序,可能不需要链接步骤。在其他情况下,例如在IDE(集成开发环境)中,链接器和编译器可以一起调用。在其他情况下,可能会使用复杂的make脚本或解决方案文件来告诉环境如何构建最终应用程序。

也有解释性语言表现不同。口译语言依赖于特殊解释程序的机器代码。在基本级别上,解释器解析源代码,并立即将命令转换为新的机器代码并执行它们。现代解释器,有时也称为运行时环境虚拟机,要复杂得多:一次评估源代码的整个部分,在可能的情况下进行缓存和优化,以及处理复杂的内存管理任务。类似于汇编代码,也可以将解释后的语言预编译为较低级的中间语言或字节码。


24
+1:不错,但简化了答案-并非所有汇编指令都以1:1的形式转换为机器指令,并且目标文件还可能包含其他数据(重定位信息,符号表等)
Christoph

5
为您的第一个期刊添加了狡猾的单词,并对其进行了编辑以使第二更清晰。
Joel Coehoorn

2
@Christoph:您说“并非所有汇编指令都按1:1转换为机器指令”,请举一个例子。
Olof Forshell

5
@Olof:RISC架构有时提供一组件级的虚拟指令集-例如MIPS伪指令(en.wikipedia.org/wiki/MIPS_architecture#Pseudo_instructions
克里斯托夫

3
@Panzercrisis汇编程序未添加任何内容。这是您对实际机器指令编写的内容的直接翻译。而且我不会将编译器放入的多余代码称为“不必要的”
Joel Coehoorn 2013年

125

其他答案很好地描述了两者之间的差异,但您也要求提供视觉效果。这是一个图表,显示了它们从C代码到可执行文件的过程。


3
我发现这确实有帮助,但是它缺少“机器码”标签
Alexx Roche 2013年

因此,在可执行代码级别,它等同于机器代码吗?
CMCDragonkai 2014年

3
在此图的上下文中,“目标代码”是机器代码。
Graphics Noob 2014年

5
实际上,目标代码和可执行代码都是机器代码。区别在于目标代码不是完整的程序。如图所示,它需要与其他帮助程序库/模块代码结合在一起,以形成完整的可执行程序/代码。
okey_on

@okeyxyz可以直接在哪个级别上被处理器直接执行?在汇编程序之后,在链接程序之后,在加载程序之后,在转换为微控制器之后?
Celeritas

49

汇编代码是机器代码的可读形式:

mov eax, 77
jmp anywhere

机器码是纯十六进制代码:

5F 3A E3 F1

我假设您的意思是目标代码与目标文件中的一样。这是机器代码的一种变体,不同之处在于对跳转进行了某种参数化设置,以便链接程序可以填充它们。

汇编程序用于将汇编代码转换为机器代码(目标代码)。链接程序链接多个目标(和库)文件以生成可执行文件。

我曾经用纯十六进制编写了一个汇编程序(没有汇编程序),幸运的是,这种方法可以追溯到旧的(古老的)6502上。但是我很高兴有奔腾操作码的汇编程序。


76
不不不不。机器代码不是十六进制代码。它是纯二进制的。十六进制代码只是二进制的方便表示。
布列塔尼

56
如果我们真的要走极端,那不是二进制,那是电路中的蓄电量。;-)
Toon Krijthe 09年

17
当然是。十六进制与您称为“机器代码”之间存在某种关系,但是说十六进制机器代码并不是很准确。这就是我要说的。
布列塔尼

9
@Breton从这个意义上说,没有“十六进制代码”这样的东西对吗?“十六进制代码”只是查看机器代码的一种方式。您可以按十六进制,二进制,八进制,十进制或您喜欢的方式查看机器代码。同样在这种意义上,也没有“二进制代码”。同样,“二进制代码”只是查看机器代码的一种方式。
Utku

9
@Breton您所说的并没有太大的意义。二进制是一种表示方式,就像十六进制一样。如果不是十六进制,则也不是二进制。
Koray Tugay

18

8B 5D 32 是机器码

mov ebx, [ebp+32h] 正在组装

lmylib.so包含8B 5D 32目标代码


8

尚未提到的一点是,有几种不同类型的汇编代码。以最基本的形式,必须将指令中使用的所有数字指定为常量。例如:

$ 1902:BD 37 14:LDA $ 1437,X
$ 1905:85 03:STA $ 03
$ 1907:85 09:STA $ 09
$ 1909:CA:DEX
$ 190A:10:BPL $ 1902

上面的代码如果存储在Atari 2600墨盒中的地址$ 1900上,将显示从地址为$ 1437开始的表中提取的许多不同颜色的行。在某些工具上,输入地址以及上面一行的最右边部分,将存储在中间列中的值存储到内存中,并从以下地址开始下一行。以这种形式键入代码比以十六进制键入要方便得多,但是必须知道所有内容的精确地址。

大多数汇编器都允许使用符号地址。上面的代码将更像是这样写:

rainbow_lp:
  lda ColorTbl,x
  STA WSYNC
  斯塔·科鲁布克
  右旋糖酐
  bpl rainbow_lp

汇编器将自动调整LDA指令,因此它将引用映射到标签ColorTbl的任何地址。与人们必须手动输入和维护所有地址的情况相比,使用这种形式的汇编程序使编写和编辑代码容易得多。


1
+1。还有一点:汇编语言语法也不同,最著名的是Intel和AT&T
informatik01

1
@ informatik01:英特尔8080助记符与Zilog Z80怎么样?我想这早于英特尔与AT&T的语法大战。
supercat 2014年

不用争论,我只是提到了这方面(不同的语法),并给出了两种最流行/众所周知/著名的语法的示例。
informatik01

4

源代码,汇编代码,机器代码,目标代码,字节代码,可执行文件和库文件。

对于大多数人来说,所有这些术语通常会使他们感到困惑,因为他们认为它们是互斥的。请参阅图以了解它们之间的关系。每个术语的说明如下。


代码类型


源代码

可读(编程)语言的指令


高级代码

用高级(编程)语言编写的指令,
例如C,C ++和Java程序


汇编代码

用汇编语言(一种低级编程语言)编写的指令。作为编译过程的第一步,高级代码将转换为这种形式。是汇编代码,然后将其转换为实际的机器代码。在大多数系统上,这两个步骤是在编译过程中自动执行的。
例如,program.asm


目标码

编译过程的产物。它可以是机器码或字节码的形式。
例如,file.o


机器码

机器语言说明。
例如a.out


字节码

可以由诸如JVM之类的解释器执行的中间形式的指令。
例如,Java类文件


可执行文件

链接过程的产物。它们是可以由CPU直接执行的机器代码。
例如.exe文件。

请注意,在某些情况下,包含字节码或脚本语言指令的文件也可以视为可执行文件。


库文件

出于不同的原因(例如可重用性),一些代码被编译成这种形式,后来被可执行文件使用。


1
我要指出,就人类编写和/或维护的最严格的代码而言,并不是所有的汇编都是真正的代码。通常,它是由源代码机器生成的,并且从来不打算供人类使用(例如,gcc实际上确实创建了asm文本,然后将其输入到单独的汇编器中,而不是在cc1可执行文件中内置了汇编器)。我认为asm圈子应该伸出“ source”圈子的左侧,因为有些asm只是asm,而不是source。当然,它从来都不是目标代码,但是一些asm是从源文件到目标文件的一步。
彼得·科德斯

@PeterCordes非常感谢您的评论。我不知道您对gcc的工作怎么说。但是,恐怕我不能完全同意你的看法。我的意思是,源代码是使用人类可读的编程语言编写的东西。它可能是人类编写或维护的,也可能不是。我相信您会知道反编译器。从您的角度来看,您会将此类编译器的产品归为哪一类?源代码还是其他?如果我错了,请纠正我。总是欢迎进一步的评论。
Bertram Gilfoyle,

1

汇编代码在这里讨论。

“汇编语言是用于计算机编程的一种低级语言。它实现了数字机器代码和对特定CPU架构进行编程所需的其他常量的符号表示。”

这里讨论机器代码。

“机器代码或机器语言是由计算机的中央处理单元直接执行的指令和数据的系统。”

基本上,汇编代码是该语言,并且由汇编器(类似于编译器)将其翻译为目标代码(CPU运行的本机代码)。


1

我认为这些是主要区别

  • 代码的可读性
  • 控制您的代码在做什么

另一方面,可读性可以使代码在创建后的6个月内得以改进或替换,如果性能至关重要,则可能需要使用低级语言来定位生产中将要使用的特定硬件,以便获得执行速度更快。

当今的IMO,计算机的速度足以使程序员使用OOP快速执行。


1

汇编是人类可以理解的简短描述性术语,可以直接转换为CPU实际使用的机器代码。

虽然有些人可以理解,但是汇编程序仍然很低级。做任何有用的事情都需要很多代码。

因此,我们改为使用高级语言,例如C,BASIC,FORTAN(好的,我知道我已经约会了)。编译时会生成目标代码。早期的语言以机器语言作为目标代码。

如今,许多语言(例如JAVA和C#)通常会编译为一种字节码,该字节码不是机器码,而是一种在运行时易于解释以产生机器码的字节码。


您对Java和C#的评论-都使用即时编译,这样就不会解释字节码。C#(通常是.NET)会编译为中间语言(IL),然后将其JIT转换为目标CPU的本机语言。
Craig Shearer

-1

程序的源文件被编译成目标文件,然后链接程序将这些目标文件链接在一起,生成一个可执行文件,其中包括体系结构的机器代码。

目标文件和可执行文件在通过文本编辑器打开时都以可打印和不可打印字符的形式涉及体系结构的机器代码。

尽管如此,文件之间的二分法是目标文件可能包含未解析的外部引用(printf例如)。因此,它可能需要与其他目标文件链接。也就是说,需要解析未解决的外部引用,以便通过与其他目标文件(例如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.