地址无关代码
在计算机领域中,地址无关代码 (英文: position-independent code,缩写为PIC),又称地址无关可执行文件 (英文: position-independent executable,缩写为PIE) ,是指可在主存储器中任意位置正确地运行,而不受其绝对地址影响的一种机器码。PIC广泛使用于共享库,使得同一个库中的代码能够被加载到不同进程的地址空间中。PIC还用于缺少内存管理单元的计算机系统中, [1] 使得操作系统能够在单一的地址空间中将不同的运行程序隔离开来。
地址无关代码能够在不做修改的情况下被复制到内存中的任意位置。这一点不同于重定位代码,因为重定位代码需要经过链接器或加载器的特殊处理才能确定合适的运行时内存地址。 地址无关代码需要在源代码级别遵循一套特定的语义,并且需要编译器的支持。那些引用了绝对内存地址的指令(比如绝对跳转指令)必须被替换为PC相对寻址指令。这些间接处理过程可能导致PIC的运行效率下降,但是目前大多数处理器对PIC都有很好的支持,使得这效率上的这一点点下降基本可以忽略。 [2]
– 汇编器也对此专门做了优化。当我们使用寻址方式标签(%rip)时,汇编器不会将其看作rip + 标签,而是会在汇编时就计算出标签距离此指令的下一条指令的地址的距离,然后用距离替换标签
-
汇编语言是机器码的human-readable版本。虽说如此,汇编语法现在的主流也有两大阵营:Intel语法与GAS语法。其最显著的区别就在于,Intel语法的组成是「指令+目的+源」,而GAS语法的组成是「指令+源+目的」
-
rip寄存器中的值是下一条指令地址
LLVM 和 GCC
在类Unix系统上主要有两大阵营:GCC和LLVM. GCC包括C编译器gcc、调试器gdb等,LLVM项目包括C编译器clang、调试器lldb等。对于编译器,GCC的思路是对于每一个CPU架构、每一种操作系统,都开发一个对应的编译器,将代码直接编译成对应的可执行文件;而LLVM项目的思路则是将编译过程分为前端和后端,无论是在什么平台、什么CPU架构下,编译器前端都是相同的,将源代码编译成llvm中间码(IR). 而后端则是将IR再翻译成对应操作系统中对应CPU架构下的可执行文件。
dispatch_apply
然而 GCD 给我们提供了一种快速迭代方法 dispatch_apply. dispatch_apply 方法则可以智能管理线程,始终是五六个子线程循环使用,这也是导致速度较慢的原因。实际开发中如果不考虑系统性能肆意开启子线程,可能会出现线程拥堵(假死)、程序崩溃