macOS上的汇编入门(十三)——从编译到执行

作为这一系列文章中的最后一篇,这篇文章我打算讨论的是从编译到执行的全过程。因为许多地方都是要有了汇编的基础知识以后才方便讨论,所以我把它放到了最后一篇。

编译

编译并不是对汇编代码来说的,而是对更高级的语言,如C、C++来说的。如果一个语言最终的编译结果是可执行文件,那么它一定会先被编译为汇编语言,然后再被汇编、链接为可执行文件。对于C和C++来说,大部分的编译器都支持输出汇编结果。比如说对于test.c, 我们想查看其编译后的汇编代码,只需要在命令行中键入

clang test.c -S -o test.s

然后就会生成一个包含其汇编代码的test.s文件。

研究编译器生成的汇编代码很有意义。因为现代的编译器,其都针对不同的平台、架构有许多优化,这对于我们写汇编代码是很有意义的。比如说,对

return 0;

的编译结果,是

xorl	%eax, %eax
retq

事实上,通过异或自身来清零这一操作,在任何架构上都是最高效的。

汇编

所谓汇编,就是输入我们的汇编代码,输出目标文件。什么是目标文件呢?假设我们有一个汇编文件test.s, 然后我们利用

as test.s -o test.o

生成一个test.o文件。然后,我们在终端下利用file指令查看其文件类型:

$ file test.o
test.o: Mach-O 64-bit object x86_64

可以看到, 这个文件是object, 也就是目标文件。

那么,目标文件是做什么用的呢?要了解这个,首先我们需要知道「汇编」这一步骤究竟做了什么。

我们知道,汇编语言可以看作机器码的human-readable版本。因此,从最直观来看,汇编只需要把汇编代码翻译为机器码就ok了,也就是汇编代码直接变成可执行文件。这个粗略来看是对的,对于大多数代码来说,确实直接翻译为机器码就好了。但是,如果真的是这样,随着人们写的代码越来越多,汇编器的有一项工作的负担就越来越重——翻译符号。我们之前在汇编语言中大量运用了标签,一个标签就对应一个地址。此外,我们也可以引用别的文件、动态链接库的标签。因此,对于一个标签,其可能的情况有好多好多种。所以,人们就把这部分功能从汇编器中解放出来,同时,汇编器就变成了对于一个汇编文件,输出其目标文件。目标文件几乎包含的就是可执行文件中的机器码,但是标签部分却是空缺的。其会把所有遇到的符号放到一个符号表中,以便查阅。

举个例子,我们现在有两个汇编程序test.stmp.s, 其代码分别如下:

tmp.s:

# tmp.s
    .data
    .globl  tmp_var
tmp_var:    .quad   0x1145
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值