Assembly 对象文件';do';为什么需要它?

Assembly 对象文件';do';为什么需要它?,assembly,object-files,Assembly,Object Files,假设我有以下asm程序,exit.s: .section .text .globl _start _start: movl $1, %eax movl $0, %ebx int $0x80 运行以下命令以生成对象文件时: $ as exit.s -o exit.o 这到底在做什么?为什么需要这样做?从“从头开始编程”一书中: 目标文件是用机器语言编写的代码,但尚未完全组合在一起 我以为这就是汇编语言本身的全部意义?那么汇编程序(exit.s)和对象文件(exit.o)

假设我有以下asm程序,
exit.s

.section .text
.globl _start
_start:
    movl $1, %eax
    movl $0, %ebx
    int $0x80
运行以下命令以生成对象文件时:

$ as exit.s -o exit.o
这到底在做什么?为什么需要这样做?从“从头开始编程”一书中:

目标文件是用机器语言编写的代码,但尚未完全组合在一起

我以为这就是汇编语言本身的全部意义?那么汇编程序(exit.s)和对象文件(exit.o)之间的区别是什么呢。计算机不能同时读取这两个数据,例如,在第一行执行hextump:

0000000 2e 73 65 63 74 69 6f 6e 20 2e 74 65 78 74 0a   
000000f
为什么计算机不能直接理解这一点

这到底在干什么

即将程序集(人类可读文本)组装(翻译)为机器代码(机器可读二进制)

为什么需要这样做

因为CPU不能执行文本,所以它们只能执行机器代码

为什么计算机不能直接理解这一点

首先,第一行是对汇编程序的指令,而不是指令。这些行告诉装配工如何装配,而不是装配什么


其次,设计和构建一个执行文本汇编的CPU肯定是可能的,但它根本没有任何优势:设计更难、构建更难、执行程序更慢,程序的大小可能是当前机器代码的3、4倍。。。正如您所见,这种方式效率不高。

Ahh,但如果您有多个asm文件,请想象一下。可能是打印.s、输入.s、文件打开.s等等。然后是main.s,它调用所有其他文件的例程来完成一些惊人的事情。在某个时候,你需要把它们缝合在一起。在main.s中使用的“callprint”需要知道打印代码的最终地址。链接器就是这样做的。它获取所有的目标文件,找出内存中的所有内容,用实际地址替换符号,然后写出可执行文件。目标文件包含所有必要的指令,但不可运行。下一个编译步骤是将目标文件与程序需要的所有库链接起来。例如,如果使用printf,链接器将静态或动态链接指令。汇编语言由“助记符”和“操作数”组成。助记符是由处理器生成的操作名。例如,movl是一个助记符,它告诉处理器将(立即)值(1)移动到eax注册表。问题是处理器不理解movl是什么意思,他只理解0和1的长逻辑序列。@DavidWohlferd你想在答案中给出一个例子,我可以接受吗?@nissimabehcera但为什么不制造一台能理解movl的计算机呢?这就是问题所在;)请注意,可以跳过目标文件步骤,让汇编程序直接生成可执行文件。然而,这使得编写库和大型程序变得困难,因为每次使用汇编程序时,汇编程序都必须重新组装整个库,这会消耗大量的时间和内存。链接器在这方面要快得多。因此,与其运行
movl$1,%eax
(或其二进制表示形式),机器实际执行的代码示例是什么?您可以使用
objdump--discombly all exit.o
查看每条指令的二进制文件。@TagC198该指令编码为
b8 01 00 00
,其中
b8
是操作代码(操作代码)而
01 00
是一个4字节立即数操作数。有关指令编码或概述,请参阅英特尔手册。顺便说一句:在20世纪60年代,有些计算机的机器代码设计为人类可读的文本。对于这样的计算机,“机器代码”和“汇编程序”是相同的。