DLL本质
DLL的本质就是暴露一些函数供给进程调用,内部也可以维护全局数据
每个进程在OS的帮助下会copy一份全局的数据给自己使用,这样就保证了进程之间共享同一个DLL没有相互的干扰。
DLL动态加载,卸载
显式加载,隐式加载
显式卸载,隐式卸载
通过引入库的方式都是隐式的。
已经存在于OS中就不需要加载了
1. OS层面上的对DLL的引用计数
第一个进程使用时,加载DLL进入OS,当所有的进程都退出了,DLL也会被卸载出OS
2. 进程对DLL显式引用计数,即使进程还在也可以卸载掉DLL
COM DLL就是这样的,通过COM API可以寻找并加载DLL,通过程序员对于COM接口使用的AddRef,Release调用,可以记载该进程是否还在使用这个DLL,当所有进程都不使用了,这个DLL也就可以卸载了。
静态链接库和动态链接库(转)
我们可以创建一种文件里面包含了很多函数和变量的目标代码,链接的时候只要把这个文件指示给链接程序就自动地从文件中查找符合要求的函数和变量进行链接,整个查找过程根本不需要我们操心。
这个文件叫做 “库(Libary)”,平时我们把编译好的目标代码存储到“库”里面,要用的时候链接程序帮我们从库里面找出来。
静态链接库:
在早期库的组织形式相对简单,里面的目标代码只能够进行静态链接,所以我们称为“静态库”,静态库的结构比较简单,其实就是把原来的目标代码放在一起,链接程序根据每一份目标代码的符号表查找相应的符号(函数和变量的名字),找到的话就把该函数里面需要定位的进行定位,然后将整块函数代码放进可执行文件里,若是找不到需要的函数就报错退出。
静态库的两个特点:
#1链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用磁盘空间较大。
#2如果有多个(调用相同库函数的)进程在内存中同时运行,内存中就存有多份相同的库函数代码,因此占用内存空间较多。
动态链接库:
动态链接库就是为了解决这些问题而诞生的技术,顾名思义,动态链接的意思就是在程序装载内存的时候才真正的把库函数代码链接进行确定它们的地址,并且就算有几个程序同时运行,内存也只存在一份函数代码。
动态库的代码必须满足这样一种条件:能够被加载到不同进程的不同地址,所以代码要经过特别的编译处理,我们把这种经过特别处理的代码叫做“位置无关代码(Position independed Code .PIC)”.
根据载入程序何时确定动态代码的逻辑地址,可以把动态装载分为两类。
#1 静态绑定(static binding)
使用静态绑定的程序一开始载入内存的时候,载入程序就会把程序所有调用到的动态代码的地址算出确定下来,这种方式使程序刚运行的初始化时间较长,不过旦完成动态装载,程序的运行速度就很快。
#2动态绑定(dynamic binding)
使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态绑定的程序。
平时默认进行链接的标准 C/C++ 函数就是动态库。
Note:
内存中的动态代码只有一份副本,但动态库的数据仍然可能有多份副本,因为每一个链接到动态的进程都可能会修改库的数据,每当出现这种情况的时候,操作系统就复制出一份数据副本,然后修改进程的地址空间映射,使它指向新的数据副本,于是进程最后修改的只是属于自己的那份数据。
中断陷入
一个应用级进程必须通过中断陷入获得内核级权限,此时执行的是中断例程。
核心的IPC调用
CPU分时调度
都必须依赖中断陷入技术
函数调用本质
PUSH “param”
CALL “address”
PUSH %EBP%
MOV %EBP%, %ESP%
……
MOV %ESP%, %EBP%
POP %EBP%
RET
POP “param”
汇编本质
立即数,寄存器,内存地址
在C/C++语言中
所有变量(自动变量,全局变量,静态变量)表达的均是内存地址
数组名,代表连续的空间的开始地址
指针变量,代表一个内存地址的32位值是一个地址值
注意变量作为左值和右值得差异
unsigned int,signed int本质
完全相同的数据空间和形式,加法计算也不区分,只在逻辑判断语句上不同
负数:补码表示
215

被折叠的 条评论
为什么被折叠?



