地址

内存管理:分页,分段,段页结合

社会主义新天地 提交于 2020-01-04 14:33:37
进程如何使用内存 进程是操作系统资源分配的最小单元。操作系统分配给进程的内存空间中包含五种段:数据段、代码段、BSS、堆、栈。 数据段 :存放程序中的静态变量和已初始化且不为零的全局变量。 代码段 :存放可执行文件的操作指令,代码段是只读的,不可进行写操作。这部分的区域在运行前已知其大小。 BSS段 ( Block Started By Symbol):存放未初始化的全局变量,在变量使用前由运行时初始化为零。 堆 :存放进程运行中被动态分配的内存,其大小不固定。 栈 :存放程序中的临时的局部变量和函数的参数值。 内存区域中以上五个段的组织形式: 逻辑地址、相对地址与物理地址 逻辑地址 : 与当前数据在内存中的物理分配地址无关的访问地址,在执行对内存的访问之前必须转化为物理地址。 相对地址 : 特殊的逻辑地址,相对于某些已知点的存储单元。 物理地址 :数据在主存中的实际位置 内存管理技术 几种内存管理技术整理 技术 简要说明 优点 缺点 固定分区 主存被分为很多大小固定的分区,进程可以装载到大于等于自身大小的分区。 实现简单 1. 有内部碎片 2. 活动进程的数目是固定的 动态分区 分区是被动态创建的,进程可以装载到正好等于自身大小的分区。 没有内部碎片,内存使用更完全 有外部碎片,需要压缩外部碎片 简单分页 主存被分为很多大小相同的帧,进程被分为很多与帧大小相同的页。要装入一个进程

页表机制

余生长醉 提交于 2020-01-04 14:32:44
分页转换功能由驻留在内存中的表来描述,该表称为页表(page table),存放在物理地址空间中。页表可看做简单的220个物理地址数组。线性到物理地址的映射功能可以简单地看做进行数组查找。线性地址的高20位构成这个数组的索引值,用于选择对应页面的物理(基)地址。线性地址的低12位给出了页面中的偏移量,加上页面的基地址最终形成对应的物理地址。由于页面基地址对齐在4K边界上,因此页面基地址的低12位肯定是0。这意味着高20位的页面基地址和12位偏移量连接组合在一起就能得到对应的物理地址。 页表中每个页表项的大小为32位。由于只需要其中的20位来存放页面的物理基地址,因此剩下的12位可用于存放诸如页面是否存在等的属性信息。如果线性地址索引的页表项被标注为存在的,则表示该项有效,我们可以从中取得页面的物理地址。如果页表项中信息表明(说明、指明)页不存在,那么当访问对应物理页面时就会产生一个异常。 1.两级页表结构 页表含有2^20(1M)个表项,而每项占用4B。如果作为一个表来存放的话,它们最多将占用4MB的内存。因此为了减少内存占用量,80x86使用了两级表。由此,高20位线性地址到物理地址的转换也被分成两步来进行,每步使用(转换)其中的10bit。 第一级表称为页目录(page directory)。它被存放在1页4K页面中,具有2^10(1K)个4B长度的表项

C语言中的强制类型转换

情到浓时终转凉″ 提交于 2020-01-04 05:38:37
C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。 例如,定义如下: int a; float b; double c; long double d; ( 假设它们所占的字节分别是 4 、 8 、 8 、 10 ,而且连续存储于某个地址空间,起始地址是 100 ,则我们可以得到如下内存分布 ) a变量就是由以地址100开始到103结束的4个字节内存空间内的0-1代码组成。b变量则是由以地址104开始到112结束的8个字节内存空间内的0-1代码组成。而在机器中,这些内存都是连续的0-1代码,机器并不知道100~103是整型而104~111是float型,所有这些类型都是编译器告知的。当我们用a时,由于前面把a定义为int型,则编译器知道从a的地址开始向后取4个字节再把它解释成int型。那么(float)a,就是先按照int类型取出该数值,再将该数值按照int to float的规则转换成float型。所以强制类型转换就是按照某个变量的类型取出该变量的值,再按照***to***的规则进行强制转转换。如果是(类型名

通信协议中的地址对齐数问题

杀马特。学长 韩版系。学妹 提交于 2020-01-04 02:43:32
通信协议中的地址对齐数 地址对齐数这个东西,实际上并不陌生了,在接触struct结构体的时候就遇到了,在这里也不多赘述,主要聊聊在通信协议中因为地址对齐数遇到的问题。 对于UDP/TCP通信,除了可以传递“行文本”之外,同样可以传递“字节流”。 Qt中常用的字节流就是QByteArray,通常采用的方式是: 结构体 <=> QByteArray 通常实现的是结构体和字节流的相互转化,这点不多说,我准备下一篇博客介绍一下这个转化过程,现在聊一聊转化过程中遇到的坑。 结构体因为“地址对齐数”的原因,可能会出现部分空间空着不使用的情况,如下面的结构体: struct StTest { int iNum1 ; char chNum ; int iNum2 ; } ; 根据地址对齐数可以知道,这个结构体的大小为12个字节,其中char类型的在这里也是占用了4个字节,但是实际上char类型仅仅占用1个字节,这就导致了3个字节的空间是空着的,虽然空着,但也是占用着内存。 一般的通信协议的制定人员,都会考虑到这一点,使其充分利用空间,不会出现中间空的的情况。 但是,在今天,我发现我手上的一份通信协议中出现了非常智障的行为,就是没有考虑到地址对齐数(或者说他也没有其他的解决方案)导致的如果采用普通的结构体定义,会出现内存位不匹配的情况。 对于这个问题,我也是苦思冥想了好久,没找到合适的解决方案

数据库设计三大范式

主宰稳场 提交于 2020-01-03 11:43:36
数据库设计三大范式 数据库设计的三大范式 为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就叫做范式。 范式就是符合某一种设计要求的总结,要想设计一个结构合理的关系型数据库,必须满足一定的范式。 在实际开发中最常见的设计范式有三个: 1、第一范式(确保每列保持原子性) 第一范式是最基本的范式。如果数据库表中的 所有字段值都是不可分解的原子值,就说明该数据库满足第一范式。 第一范式的合理遵循需要根据系统给的实际需求来确定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成为一个数据库表的字段就行,但是如果系统经常访问“地址”属性中的“城市”部分,那么一定要把“地址”这个属性重新拆分为省份、城市、详细地址等多个部分来进行存储,这样对地址中某一个部分操作的时候将非常方便,这样设计才算满足数据库的第一范式。如下图。 上图所示的用户信息遵循第一范式的要求,这样对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。 2、第二范式(确保表中的每列都和主键相关) 第二范式在第一范式的基础上更进一层,第二范式需要确保数据库表中每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。 比如要设计一个订单信息表

计算机组成原理——第七章

五迷三道 提交于 2020-01-02 16:28:43
1.指令系统中采用不同的寻址方式的目的是: 缩短指令字长,扩大寻址空间,提高编程灵活性 2.一地址指令中,除地址译码指明的一个操作数外,另一个数用( 隐含寻址 )的方式 4.操作数在寄存器中的寻址方式是(寄存器直接寻址) 5.寄存器间接寻址 方式中,操作数存于( 主存单元 )( 寄存器指明操作数在主存中的地址 ) 7.基址寄存器寻址方式中,操作数的有效地址是( 基址寄存器BR内的值加上形式地址 ) 8.采用基址寻址,基址寄存器内容有 操作系统 确定,在 程序中不能改变 9.采用变址寻址,变址寄存器( IX )内容有用户确定,在程序执行过程中 可以改变 10.堆栈的出栈和入栈操作是相反的,入栈是先 (A)到Msp然后sp-1到sp (注意, 栈顶的地址要比下面的地址都要小 ), 出栈是sp+1到sp,然后再(A)到Msp 13.寻址方式中,立即寻址快于直接寻址快于间接寻址 14.扩展操作码的目的是: 增加指令数(特征位) 16.子程序 调用 指令完整的功能是:( 改变程序计数器的值和堆栈指针sp的值 ) 17.子程序返回指令完整的功能是:( 从堆栈中恢复程序技术器的值 ) 二.填空题 1.在直接寻址中,操作数的有效地址是X,间接寻址中:(X)相对寻址中( PC)+ X ,基址寻址中 (BR)+ X,变址寻址中(IX)+ X 2.条件转移,无条件转移,子程序调用都属于( 程序控制或跳转

CS萌新的汇编学习之路02 Learning of Assembly Language

青春壹個敷衍的年華 提交于 2020-01-02 06:28:08
第二节课 寄存器 1. 寄存器的定义: 进行信息储存的器件,是CPU中程序员可以读写的部件,通过改变各种寄存器中的内容来实现对CPU的控制 2. 寄存器的种类: 本节课学习通用寄存器和段寄存器 2.1 通用寄存器 8086CPU中,所有的寄存器都是16位的,可以存放两个字节。AX,BX,CX,DX这四个寄存器通常用来存放一般性的数据,被称为通用寄存器。 8086CPU的上一代CPU中的寄存器都是8位的,为了保证兼容,AX,BX,CX,DX这四个寄存器都可以分为两个8位的小寄存器来用。8086CPU可以一次性处理字节和字,字节(byte)是8个bit组成;字(word)是由两个字节组成(高位字节和低位字节) 例如,AX分为AH和AL (高位和低位)AH为高8位,从00H到FFH,AL为低8位,从00H到FFH。两个按照AX=AH*100H+AL组合在一起。但是在对于AL、AH的单独运算中,产生进位是不予考虑的,比如单独对AL做加法,产生的进位不会加到AH里面,AH的进位也不予添加(超出AX范围了)。但是对于AX的计算考虑在AX范围内的进位,超出AX范围不考虑(直接舍去)。 2.2 物理地址和计算物理地址的方法 CPU访问内存单元,需要给出内存单元的地址,这个唯一的地址为物理地址。 8086CPU为16位结构的CPU机,意味着运算器一次性最多能处理16位的数据,寄存器的最大宽度为16

第二章寄存器总结

痴心易碎 提交于 2020-01-02 06:27:38
1.通用寄存器 (1)数据寄存器 数据寄存器共有4个寄存器AX、BX、CX、DX,用来保存操作数或运算结果等信息。 AX寄存器称为累加器。使用频度最高,用于算术、逻辑运算以及与外设传送信息等。 BX寄存器称为基址寄存器。常用于存放存储器地址。 CX寄存器称为计数器。一般作为循环或串操作等指令中的隐含计数器。 DX寄存器称为数据寄存器。常用来存放双字数据的高16位,或存放外设端口地址。 (2)变址和指针寄存器 变址和指针寄存器包括SI、DI、SP、BP 4个16位寄存器,主要用于存放某个存储单元的偏移地址。 SI是源变址寄存器。 DI是目的变址寄存器,在字符串操作中,SI和DI都具有自动增量或减量的功能。 SP为堆栈指针寄存器,用于存放当前堆栈段中栈顶的偏移地址。 BP为基址指针寄存器,用于存放堆栈段中某一存储单元的偏移地址。 2.段寄存器 8086 CPU的4个16位的段寄存器分别称为代码段寄存器CS,数据段寄存器DS,堆栈段寄存器SS,附加数据段寄存器ES。段寄存器用来确定该段在内存中的起始地址。 代码段用来存放程序的指令序列。CS存放代码段的段首址,指令指针寄存器IP指示代码段中指令的偏移地址。 3.指令指针 8086 CPU中的指令指针IP,它总是保存下一次将要从主存中取出指令的偏移地址,偏移地址的值为该指令到所在段段首址的字节距离。在目标程序运行时

汇编语言——寄存器(CPU的工作原理 ax,bx,cx,dx通用寄存器 cs代码段寄存器)

…衆ロ難τιáo~ 提交于 2020-01-02 06:22:20
寄存器 一个典型的CPU由运算器、控制器、寄存器等器件组成,这些器件靠内部总线相连。(外部总线是上一篇博客说的内存总线,数据总线,控制总线) 内部总线实现CPU内部各个器件之间的联系。 外部总线实现CPU和主板上其它器件的联系。 CPU中主要的部件是寄存器,寄存器是CPU中我们可以使用指令读写的部件(通过改变各种寄存器的内容来实现对CPU的控制) 不同的CPU寄存器的个数也不同,8086CPU有14个寄存器 它们的名称为:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。 1、通用寄存器 a.简介 8086CPU所有的寄存器都是16位的,可以存放两个字节。(1Byte=8bit) AX、BX、CX、DX 通常用来存放一般性数据被称为 通用寄存器。 一个16位寄存器所能存储的数据的最大值为: 2 16 -1 。 示例: 数据:20000 二进制表示:0100111000100000 在寄存器AX中的存储: 四个寄存器都可以分为 两个独立的8位寄存器 使用。 AX可以分为AH和AL; BX可以分为BH和BL;CX可以分为CH和CL; DX可以分为DH和DL。 AX的低8位(0位~7位)构成了 AL寄存器 ,高8位(8位~15位)构成了 AH寄存器 ,它们都是可以独立使用的8位寄存器。一个8位寄存器所能存储的数据的最大值是2 8 -1。 b.汇编指令

第二章寄存器

我只是一个虾纸丫 提交于 2020-01-02 06:22:04
第一章需要补充说明的是内存地址空间,对CPU来说,系统中的所有存储单元都处于一个统一的逻辑存储器中,它的容量受CPU寻址能力的限制,这个逻辑存储器就是我们所说的内存地址空间。这个概念比较抽象,需要进行一些编程实践增加更感性的认识。 在CPU中,有四种主要的部件。运算器,控制器,寄存器,内部总线。这里的内部总线用于CPU内部进行各种信息的传递,与第一章所讲的控制总线,数据总线,地址总线不同,第一章所描述的总线属于外部总线,作为CPU与外部期间进行信息传递的通路。运算器用于各种信息的处理,寄存器用于信息的处理,控制器用于控制信息的处理。对于利用汇编编程来说,寄存器是主要操作的部件,不同的CPU中寄存器的个数和种类是不同的。 8086CPU所有的寄存器都是16位的,可以存放两个字节,一个字节8位。AX、BX、CX、DX 通常用来存放一般性数据被称为通用寄存器。通用寄存器(重点)8086上一代CPU中的寄存器都是8位的,为保证兼容性,这四个寄存器都可以分为两个独立的8位寄存器使用。AX可以分为AH和AL;BX可以分为BH和BL;CX可以分为CH和CL; DX可以分为DH和DL。 AX的低8位(0位~7位)构成了AL寄存器,高8位(8位~15位)构成了AH寄存器。AH和AL寄存器是可以独立使用的8位寄存器,如果当成是8位寄存器使用,那么他们就是独立的,没有任何关系。