汇编
汇编器会接收汇编代码,将它转换成二进制的机械码,生成目标文件(后缀是 .o),机械码可以直接被 CPU 辨认并履行。大年夜目标代码可以猜出来,最终的目标文件(机械码)也是分段的,这重要有以下三个原因:
- 分段可以将数据和代码区分开。个中代码只读,数据可写,便利权限治理,避免指令被改写,进步安然性。
- 现代 CPU 一般有本身的数据缓存和指令缓存,区分存储有助于进步缓存射中率。
- 当多个过程同时运行时,他们的指令可以被共享,如许能节俭内存。
段分别我们并不遥远,比如敕令行中的 objcopy 可以自行添加自定义的段名,C 说话的 __attribute((section(段名)))__ 可以把变量定义在某个特定名称的段中。
对于一个目标文件来说,文件的最开首(也叫作 ELF 头)记录了目标文件的根本信息,法度榜样人口地址,以及段表的地位,相当于是对文件的┞符体描述。接下来的重点是段表,它记录了每个段的段名,长度,偏移量。比较常用的段有:
- .strtab 段: 字符串长度不定,分开存放浪费空间(因为须要内存对齐),是以可以同一放到字符串表(也就是 .strtab 段)中进行治理。字符串之间用\0 瓜分,所以凡是引用字符串的处所用一个数字就可以代表。
- .symtab: 表示符号表。符号表同一治理所有符号,比如变量名,函数名。符号表可以懂得为一缸莨狁,每行都有符号名(数字)、符号类型憾?号值(存储地址)
- .rel 段: 它表示一系列重定位表。这个表重要在链接时用到,下面会具体解释。
链接
在一个目标文件中,弗成能所有变量和函数都定义在文件内部。比如 strlen 函数就是一个被调用的外部函数,此时就须要把 main.o 这个目标文件和包含了 strlen函数实现的目标文件链接起来。我们知道函数调用对应到汇编其实是 jump 指令,后面写上被调用函数的地址,但在生成 main.o 的过程中,strlen() 函数的地址并不知道,所以只能先用 0 来代替,直到最后链接时,才会修改成真实的地址。
链接器就是靠侧重定位表来知道哪些处所须要被重定位的。每个可能存在重定位的段都邑有对应的重定位表。在链接阶段,链接器会根据重定位表中,须要重定位的内容,去其余目标文件中找到地址并进行重定位。
有时刻我们还会听到动态链接这个名词,它表示重定位产生在运行时而非编译后。动态链接可以节俭内存,但也会带来加载的机能问题,这里不具体解释,感兴趣的读者可以浏览《法度榜样员的自我教养》这本书。
预处理
最后简单描述一下预处理。预处理主如果处理一些宏定义,比如#define、#include、#if 等。预处理的实现有很多种,有的编译器会在词法分析前先辈行预处理,调换掉落所有 # 开首的宏,而有的编译器则是在词法分析的过程中进行预处理。当分析到 # 开首的单词时才进行调换。固然先预处理再词法分析比较相符直觉,但在实际应用中,GCC 应用的倒是一边词法分析,一边预处理的筹划。
编译 VS 解释
既然说到了 JSPatch 这一类动态化的 iOS 开辟对象,我就斗胆猜测一下腾讯 OCS 的实现道理,今朝介绍 OCS 的文┞仿寥寥无几,因为苹不雅公司的请求,原文已经被删除,大年夜新浪博客上摘录了一份: OCS ——史上最猖狂的 iOS 动态化筹划。如不雅用一句话来概述,那么就是 OCS 是一个 Objective-C 说冥器。
以 C 说话为例,有异常多的操作最终都依附于 glibc 这个动态链接库。包含但不限于字符串处理(strlen、strcpy)、旌旗灯号处理、socket、线程、IO、动态内存分屏(malloc)等等。这一点很好懂得,如不雅回想一下之前编译器的工作道理,我们会发明它仅仅是处理了说话的语法,比如变量定义,函数声明和调用等等。至于说话的功能, 比如内存治理,內建的类型,一些须要功能的实现等等。如不雅要对运行时库进行分类,大年夜概有两类。一种是说话自身功能的实现,比如一些內建类型,内置的函数;另一种则是说话无关的基本功能,好交手件 IO,socket 等等。
编译器以中心代码为界线,又可以分前端和后端。比如 clang 就是一个前端对象,而 LLVM 则负责后端处理。另一个有名对象 GCC(GNU Compile Collection)则是一个套装,包办了前后端的所有义务。前端重要负责预处理、词法分析、语法分析,最毕生成说话无关的中心代码。后端重要负责目标代码的生成和优化。
关于编译道理的基本常识固然逝世板,但控制这些常识有助于我们懂得一些有效的,但不太轻易懂得的概念。接下来,我们简单看一下其余说话是若何运行的。
Java
在 Java 代码的履行过程中,可以简单分为编译和履行两步。Java 的编译器起首会把 .java 格局的源码编译成 .class 格局的字节码。字节码对应到 C 说话的编译体系中就是中心码,Java 虚拟机履行这些中心码获得最终结不雅。
回想一下上文对中心码的解释,一方面它与说话无关,仅仅描述客不雅事实。另一方面它和目标代码的差距并不大年夜,已经包含了对存放器和栈的处理,仅仅是抽象了 CPU 架构罢了,只要把它具体化成付啦媒台下的目标代码,就可以交给汇编器了。
推荐阅读
【51CTO.com原创稿件】稀有据猜测,2017年中国差旅市场支撑或跨越3000亿美元,将代替美国成为全球最大年夜的商旅市场。近日《2017年德国嘉惠国际商旅治理研究申报》宣布,个中稀有据表示中>>>详细阅读
地址:http://www.17bianji.com/lsqh/35915.html
1/2 1