操作系统_程序的装入

  我们知道,程序要执行,必须被CPU调用执行,而前提是装入到主存中。所以程序的装入对于操作系统来说,是一件非常重要的工作。要了解程序是如何装入到主存中,我们首先来了解下逻辑地址和物理地址

  主存的存储单元以字节为单位编址,每个存储单元都有一个地址与其对应。假定主存的容量是256M,即256*1024*1024=2^28个字节(256M=256*2^10K=256*2^10*2^10B),则该主存就有2^28个字节的存储空间,起地址编号为0,1,2,…………2^28-1。这些地址称为主存的物理地址(也称为绝对地址),物理地址对应的主存空间称为物理地址空间;然而,在多道程序设计系统(如windows,linux等)中,主存中同时存放了多个用户作业。每次调入运行时,操作系统将根据主存的使用情况为用户分配主存空间,每个用户不可能预先知道其作业存放的主存的具体位置(物理位置)。因此,在用户程序中不能使用主存的物理地址。为了方便程序的编制,每个用户可以认为自己作业系统和数据存放在一组从0地址开始的连续空间中。用户程序所使用的地址称为逻辑地址(也叫相对地址或虚地址),逻辑地址对应的存储空间成为逻辑地址空间。

  下面我们来开始看看程序载入的一般步骤:编译-链接-装入。首先编译,有编译程序(Complier)将用户源代码编译城若干目标模块(Object
Module)(.obj文件);然后链接,有连接程序(Linker)将编译后形成的一组目标以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load
Module)(如.exe文件);最后装入,由装入程序(Loader)将装入模块装入主存。看下图

  将一个装入模块装入主存中,有3种方法:绝对装入方式,
静态重定位装入方式, 动态重定位装入方式。

  1:绝对装入方式。如果在编译时就知道了程序驻留在主存的具体位置,则编译程序将产生的物理地址的目标代码。绝对装入程序按照装入模块的地址,将程序和数据装入主存。模块装入后,由于程序中的逻辑地址和实际主存的地址完全相同,
所以不需要修改程序和数据的地址。
  但是,如果要程序猿直接给出程序和数据的物理地址,则要求比较高,不但要求程序猿熟悉主存的使用情况,而且一旦要修改某个地址,就可能要修改程序中所以地址,所以在程序中往往使用符号地址,在编译或汇编时将其转换为物理地址。
  注意事项:绝对装入方式只能将目标模块装入到主存事先指定的固定位置,只适用于单道程序环境。看下图。
 
  

  2:静态重定位装入方式。在装入作业时,把该作业中的指令指令和数据地址一次性全部转换为物理地址,这样在作业执行过程中无需再进行地址转换工作,这种地址转换方式称为静态重定位,这种作业装入方式称为静态重定位装入方式。如图。
 
 

  3:动态重定位装入方式。在装入作业时,装入程序直接把作业装入到所分配的主存区域中。在作业执行过程中,随着每条指令或数据的访问,由硬件地址转换机制自动地将指令中的逻辑地址转换称对应的物理地址。这种地址转换的方式是在作业执行的过程中动态完成的,所以叫动态重定位。如图。
 
 
 
注意,动态定位由硬件(基地址寄存器)和软件相互配合实现。
 采用动态重定位,由于装入主存的作业仍保持逻辑地址,所以,必要时可改变作业在主存中的存放区域。若改变了存储区域,作业仍能正确执行,则称程序是可浮动的。采用动态重定位的系统支持程序浮动(碎片整理时用到)。而静态重定位由于装入主存时作业信息都已转化为物理地址,执行过程中不再进行地址转换,所以作业执行过程中不能改变存放位置,即采用静态重定位的系统不支持程序浮动。

PS——参照机械工业出版社《操作系统教程》.
 
    图片来自Google Images.
  

时间: 2024-10-06 22:03:18

操作系统_程序的装入的相关文章

操作系统_程序的链接

程序经过编译后,得到一组目标模块(Object Module),再经过链接程序将这组目标模块链接起来,形成一个完整的装入模块.如图.经过编译后得到三个目标模块A,B,C,它们的长度分别为L,M,N.其中B和C属于外部调用符号.根据链接时间的不同,程序的链接可分为三种方式:静态链接,装入时动态链接,运行时动态链接     1:静态链接.在程序运行之前,首先将各个目标模块以及所需要的库函数链接成一个完整的装入模块,又称为可执行文件,运行时可直接将它装入主存. 2:装入时链接.用户源程序经过编译后得到

【操作系统总结】存储器管理-程序的装入与连接,连续分配存储管理方式

程序的装入与连接 程序要经过编译,链接,装入才能运行 绝对转入方式 将程序装入事先指定的地址,程序装入以后逻辑地址与实际内存地址相同.要求程序员非常熟悉内存地址 可重定位方式 根据内存的具体情况将程序装入适当的位置,把装入时对程序和数据的地址修改过程称为重定位. 动态运行时的装入方式 程序对换的时候内存是改变的 可重定位不允许程序运行时在内存中移动位置.动态运行时的装入程序在把装入模块装入内存后,并不立即把装入模块转换程物理地址,而是吧这中地址转换推迟到程序真正要求执行时进行. 程序的链接 静态

程序的装入重新定位

程序的装入为了阐述上的方便,我们先介绍一个无需进行链接的单个目标模块的装入过程.该目标模块也就是装入模块.在将一个装入模块装入内存时,可以有绝对装入方式.可重定位装入方式和动态运行时装入方式,下面分别简述之.第四章 存 储 器 管 理 ·119·1.绝对装入方式(Absolute Loading Mode)在编译时,如果知道程序将驻留在内存的什么位置,那么,编译程序将产生绝对地址的目标代码.例如,事先已知用户程序(进程)驻留在从 R 处开始的位置,则编译程序所产生的目标模块(即装入模块)便从 R

Breaseman算法绘制圆形|中点算法绘制圆形_程序片段

Breaseman算法绘制圆形|中点算法绘制圆形_程序片段 1. Breaseman算法绘制圆形程序 由于算法的特殊性,限制绘制第一象限部分,其他部分通过旋转绘制. 1 void CCGProjectWorkView::bresenHam_1P4Circle(int radium, const float lineColor[]) 2 { 3 int pointX, pointY, deltD, deltHD, deltDV, direction; 4 pointX = 0; 5 pointY

逻辑运算_三元运算符_程序流程控制

 //逻辑运算符   /*       逻辑运算符用于连接布尔型表达式,在Java中不可以写成3<x<6,应该写成x>3 & x<6 .      "&"和"&&"的区别: 单&时,左边无论真假,右边都进行运算:       双&时,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算.       "|"和"||"的区别同理,||表示:当左边为真

.net core使用HttpClient发送代理请求_程序内抓包_Fiddler抓包

原文:.net core使用HttpClient发送代理请求_程序内抓包_Fiddler抓包 前言:  通过Fiddler抓取浏览器请求数据,相信大家已经都会用了,我们知道Fiddler是通过在本机计算器添加一个默认的代理服务器来实现的抓包数据的,端口号为:8888. 其实当我们打开Fiddler的设置也可以看到: 然后查看本地计算器的网络代理设置: 基于上面的原理,Fiddler就实现了经过本机计算器请求的数据抓包了... 那么,我们通过C#代码,在.net Core中使用HttpClient

操作系统_上午

根据架构图—画出请求数据流 —根据数据流经过的节点分析问题 负载机—经过网络传输到—应用服务器—跑服务—空闲中间件连接池(web请求连接池)_处理代码—通过网络把sql发送到—数据库连接池—请求发送到数据库服务器—数据库执行sql语句—将数据结果通过网络返回应用服务器—应用服务器对进程和线程唤醒—返回数据结果继续执行代码—将返回结果return—通过网络返回客户端 分析原因: 负载机(硬件)—网络—应用服务器(硬件)—数据库服务器(硬件)—web容器连接池—数据库连接池—sql执行过程—代码的业

windows操作系统对于程序运行时堆栈的管理的研究

通过下面的代码得出了一个结论: 在windows操作系统中,栈空间不会释放,而是如果现有的栈空间满足函数的运行,则不再申请新的栈空间,但函数退出后也不释放栈空间:如果函数运行时占空间不够,则需要再申请新的空间: 使用malloc动态申请的空间因为位于堆空间,free后可以直接释放 #include <stdio.h> #include <Windows.h> int hello1() { int arra[1000*60];//占用的栈空间大小大概为0.2MB int i=0; f

linux学习之操作系统与程序

预编译:预编译过程主要处理那些源代码中以"#"开始的预编译指令.比如"#include","#define"等1.将所有的"#define" 删除并且展开所有的宏定义2.处理所有条件预编译指令.比如:#if #ifdef #endif #else3.处理#include 预编译指令 将被包涵的文件插入到该预编译指令位置.这个过程是递归的.4.删除所有的注释"//" 和"/××/"5.添加