概念:
内存是用于存放数据的硬件,程序在执行前应该放在内存中才能够被cpu处理。
在多道程序中,系统中会有多个进程在内存中同时运行,那如区分各个进程的数据都存在什么地方呢?事实上,就像酒店管理人员为方便管理,给每个房间编一个房间号一样,操作系统会为每个存储单元分配地址
逻辑地址与物理地址:
程序在被编译时只需要确定变量存放的相对地址,cpu在执行运算时,会根据进程的起始地址再去计算逻辑地址就得到了物理地址。
从写程序到程序执行的过程
程序员可以编辑一系列语言代码,比如c语言中的.c文件,然后经过编译器编译后,形成与它对应的目标模块,而这些目标模块其实就是用机器语言表示的一系列等价的指令集合,比如x = x + 1的例子。编译的过程就可以理解为把高级语言翻译成机器语言的过程,这些目标模块包含的指令的地址其实就是逻辑地址,每个目标模块的逻辑地址都是从0开始,之后通过连接沉痼的连接会把这些目标模块组装成完成的装入模块,并且形成一个完整的装入模块,并且形成一个完整的逻辑地址空间,比如windows系统中的.exe文件其实就是完整的装入模块,又称为可执行文件。最后 装入程序把装入模块放入内存相应的位置当中,形成最终的物理地址,接下来cpu就可以正式地执行这个程序了。所以,从真个过程来看,从逻辑地址到物理地址地转换,应该是装入程序关心解决地问题。
装入模块装入内存的过程
编译器会将每条高级语言的指令给转成相应的机器语言,每条指令都会占据一个存储单元,逻辑地址从0开始递增,每条指令涉及的变量可能会存在其他的存储单元如下图中,相对位置为80的逻辑地址(这个时便宜地址,相对初始地址来说的),这并不是变量在内存中真正的逻辑地址。但这并不绝对,如果说,从物理内存地址为0的地方开始存放的话,那么这些指令所使用的地址会保持和装入模块的逻辑地址一样,不需要进行改变。
但是如果我们把装入模块放到了比如从内存地址为100的地方带式存放,(在装入时内存地址发生改变)这些指令包含的参数比如80和x,其实就会指向一个错误的地方。因为我本来我们希望变量a存放在相对地址为80,即物理地址为180的地方,但是如果我们不修改这些指令,最后指令有可能把1写到物理地址为80的地方,所以我们在装入的时候可以解决这些问题。
绝对装入
编译时,需要知道程序以及程序中的绝对地址(不是)将放到物理地址的哪个位置。这种方法一般用于单道程序,因为程序是从上到下执行,在编译时就可以确定每条指令的物理地址。
静态重定位
重点:装入时对所有相关地址(变量和指令地址)进行"重定位"。
动态重定位
cpu真正执行到程序时,如果像从从100处执行时,只需要把重定位寄存器的值改为100就行了,执行到其他指令时,其他地址也会动态加100