精华内容
下载资源
问答
  • 内存寻址

    2020-09-14 15:02:28
    内存寻址 1.冯诺依曼结构和哈佛结构 **哈佛结构:**程序指令和数据存储分开存储的存储器结构。 **冯诺依曼结构:**数据和代码放在一起。 2.X86内存寻址的不同时期 **逻辑地址:**通过段地址和偏移地址来表示的存储...

    内存寻址

    1.冯诺依曼结构和哈佛结构

    **哈佛结构:**程序指令和数据存储分开存储的存储器结构。

    在这里插入图片描述

    **冯诺依曼结构:**数据和代码放在一起。
    在这里插入图片描述

    2.X86内存寻址的不同时期

    **逻辑地址:**通过段地址和偏移地址来表示的存储单元的地址称为逻辑地址,记为:段地址:偏移地址。
    线性地址:线性地址也就是虚拟地址,linux用户进程使用的地址就是这个虚拟地址。
    **物理地址:**用来寻址物理存储芯片的地址,通常也就是处理器的物理地址总线所寻址的地址空间。
    **逻辑地址、线性地址和物理地址之间的转换关系:**分段机制把一个逻辑地址转换为线性地址,接着分页机制把一个线性地址转换为物理地址。
    在这里插入图片描述

    8080:可以访问16位的内存地址,可以访问64K范围内的地址空间。此时还没有段的概念,
    访问内存要通过绝对地址,因此程序中的地址必须进行硬编码。
    8086:地质总线扩展到20位,但数据总线只有16位,于是采用分段的方法实现从16位内
    存地址到20位实际地址的转换,即“映射”。
    80286:实模式+保护模式 。地质总线增加到了24位,可以访问16M的内存空间。引入保
    护模式,访问内存时要经过额外转换和检查才能获得段的起始地址。系统启动时处于实模式,
    只能访问1M空间,经过处理进入保护模式,访问空间扩展到16M。但是每个段的大小仍为
    64K。
    80386:实方式+保护方式+虚拟8086方式,地质总线和数据总线宽度一致也是32位,寻址能力达到4G。
    3.分段机制
    硬件中的分段:
    段选择符:即段标识符,16位长。处理器提供段寄存器,唯一目的是存放段选择符。
    选择符有三个域:索引,选择域和请求者的特权级。
    TI-Table Indicator(为0时从全局描述符;为1时从局部描述符)中选择相应的段描述符。RPL-Requestor Privilege Level表示请求者的特权级,Linux中有两个特权级,0表示最高特权级,对应内核态;3表示最低特权级,对应用户态。
    在这里插入图片描述
    在这里插入图片描述

    **段描述符:**每个段由8位的段描述符表示,存放在GDT和LDT中,GDT和LDT在主存中的位置和大小存放在gdtr和ldtr寄存器中。描述段的属性的一个8字节的存储单元,其中有32位基地址和20位段界限。在保护模式下,有三个类型的描述符表,分别是:全局描述符表-Global Descriptor Table,中断描述符表-Interrupt Descriptor Table及局部描述符表-Local Descriptor Table.
    全局描述符和局部描述符的区别:
    全局描述符表和局部描述符表保存的都是段描述符,记住要把段描述符和段选择符区别开来,保存在寄存器中的是段选择符,这个段选择符会到描述符表中获取对于的段描述符,然后将段描述符保存到对应寄存器的非编程寄存器中。
      (1)系统中每个CPU有属于自己的一个全局描述符表(GDT),其所在内存的基地址和其大小一起保存在CPU的gdtr寄存器中。其大小为64K,一共可保存8192个段描述符,不过第一个一般都会置空,也就是能保存8191个段描述符。第一个置空的原因是防止加电后段寄存器未经初始化就进入保护模式而使用GDT。
     (2) 而对于局部描述符表,CPU设定是每个进程可以创建属于自己的局部描述符表(LDT),当前被使用的LDT的基地址和大小一起保存在ldtr寄存器中。不过大多数用户态的liunx程序都不使用局部描述符表,所以linux内核只定义了一个缺省的LDT供大多数进程共享。描述这个局部描述符表的局部描述符表描述符保存在GDT中。
    在这里插入图片描述

    **第五个字节位的含义:**第五个字节为存储权字节。
    P:存在位,P=1,表示这个段在内存中;P=0,表示不在内存中。
    DPL(Descriptor Privilege Level):描述符特权级,用0-3来确定这个段的特权级。
    S:系统标志。S=0,则为系统段;S=1,则为用户程序的代码段、数据段或堆栈段。
    类型:第3位:E=0,数据段描述符。
    第2位:ED=0,表示向地址增大的方向扩展;ED=1,向地址减小的方向扩展。
    第1位:W=0,数据段不能写,W=1,数据段可写入。
    A:可以由操作系统使用,被linux忽略。
    第六个字节的位含义:
    G:粒度标志。G=0,段大小以字节为单位;G=1,段大小以4096的倍数计。
    D:D=0,操作数为16位;D=1,操作数为32位。

    快速访问段描述符:
    80X86提供一种附加的非编程的寄存器,里面存放8字节的段描述符。每当一个段选择符被装入段寄存器时,相应的段描述符就由内存装入到对应的非编程CPU寄存器。所以,那个段的逻辑地址转换就可以不访问主存中的GDT或LDT,处理器只需直接引用存放段描述符的CPU寄存器。
    分段单元:
    ·根据TI确定段描述符在哪一个GDT(从gdtr寄存器得到GDT的线性基地址)还是在LDT(从ldtr寄存器中得到LDT的线性基地址)中。
    ·index字段的值*8,结果与gdtr或ldtr中的内容相加,计算出段描述符的地址。
    ·逻辑地址的偏移量与段描述符Base字段的值相加就得到了线性地址。

    在这里插入图片描述
    Linux中的分段:
    Linux中段的基地址为0,而段的界限为4GB,这时任意给出一个偏移量,则等式为“0+偏移量=线性地址”,也就是说“偏移量=线性地址”。另外由于段机制规定“偏移量<4GB”,所以偏移量的范围为0H~FFFFFFFFH,这恰好是线性地址空间范围,也就是说虚拟地址直接映射到了线性地址,我们以后所提到的虚拟地址和线性地址指的也就是同一地址。
     Llinux在启动过程中设置了段寄存器的值和全局描述符表GDT的内容,内核代码中可以这样定义段:
    从定义可以看出,TI=0,这几个段都放在GDT中,index就是某个段在GDT表中的下标。内核的代码段和数据段都为最高特权级即RPL=0;对应的用户的代码段和数据段为最低特权级,RPL=3.

    展开全文
  • 内存寻址

    内存寻址在这里插入图片描述

    展开全文
  • 内存管理之内存寻址

    2019-10-06 17:30:54
    内存寻址 操作系统本身不必完全理解物理内存; 理解分页单元的一般原理, 又要更好地研究内存寻址技术在其他平台是如何实现的; 内存管理其实可以分成三个部分: 内存寻址, 内核给自己分配主存, 内核怎样给进程分配线性...

    内存寻址

    • 操作系统本身不必完全理解物理内存;
    • 理解分页单元的一般原理, 又要更好地研究内存寻址技术在其他平台是如何实现的;
    • 内存管理其实可以分成三个部分: 内存寻址, 内核给自己分配主存, 内核怎样给进程分配线性地址;

    三种内存地址

    1. 逻辑地址(logical address): 包含机器语言指令中用来指定一个操作数或一条指令的地址;
      • 在分段结构中表现出来: 由一个段(segment)和偏移量(offset或displacement)组成;
    2. 线性地址(linear address): 线性地址也称为虚拟地址(virtual address)
      • 线性地址通常用十六进制数据表示, 值的方位从0x0000 0000 到 0xffff ffff
    3. 物理地址(physical address): 用于内存芯片级内存单元寻址, 他们与从微处理器的地址引脚发送到内存总线上的电信号相对应, 物理地址由32位或64位无符号整数表示;
    4. 内存控制单元: 内存控制单元(MMU)通过一种称为分段单元(segmentation unit)的硬件电路把一个逻辑地址转换成线性地址;
      • 接着, 第二个称为分页单元(paging unit)的硬件电路把线性地址转换为一个物理地址;
      • 逻辑地址 -----> 分段单元 -----> 线性地址 -----> 分页单元 -----> 物理地址;
    5. 内存仲裁器(memory arbiter)的硬件电路插在总线和每个RAM芯片之间;
    6. DMA控制器与CPU并发操作;

    硬件中的分段

    • Intel微处理器以两种不同的方式执行地址转换, 这两种方式分别为: 实模式(real mode)和保护模式(protected mode), 现在主要是使用保护模式, 实模式只是为了兼容性;
    段选择符和段寄存器
    • 一个逻辑地址由两部分组成: 一个段标示符(segment selector)和一个指定段内相对地址的偏移量(32位字长);
    • 段寄存器的唯一目的是存放段选择符: cs, ss, ds, es, fs和gs, 六个段寄存器用于不同的目的;
      • cs 代码段寄存器, 指向包含程序指令的段;
      • ss 栈段寄存器, 指向包含当前程序栈的段;
      • ds 数据段寄存器, 指向包含静态或全局数据段;
      • es, fs 和 gs是作一般用途的寄存器, 可指向任意的数据段;
      • cs寄存器包含一个两位的字段: 用以指明CPU的当前特权即(current privilege level, CPL)
        • 0 表示最高优先级;
        • 3 表示最低优先级;
        • Linux只用0级和3级, 分别称为内核态和用户太;
    • 段描述符: 每个段由一个8字节的段描述符(segment DEscriptor)表示, 段描述符顾名思义, 它描述了段的特征;
      • 段描述符存放在全局描述符表(global descriptor table, GDT) 或局部描述符表(Local Descriptor Table, LDT)中;
      • 每个进程除了存放在GDT中的段之外, 如果还创建了附加的段, 可以存放在自己的LDT中;
      • GDT在主存中的地址和大小存放在gdtr控制寄存器中, 当前正在被使用的LDT地址和大小放在ldtr控制寄存器中;
    • 快速访问段描述符: 逻辑地址由16位段选择符和32位偏移地址组成, 段寄存器仅仅存放段选择符;
      • 段的逻辑地址转换就可以不访问主存中的GDT或LDT, 处理器主需要直接引用存放段描述符的CPU寄存器即可, 仅当段寄存器的内容改变时, 才有必要访问GDT或LDT;
    • 分段单元: 分段单元讲一个逻辑地址转换为相对应的线性地址;
      • 先检查段选择符的TI字段, 决定段描述符保存到拿一个描述符表中;
      • 从段选择符的index字段计算段描述符的地址, index字段的值乘以8, 再与gdtr或ldtr寄存器中的内容相加;
      • 把逻辑电子的偏移量与段描述符base字段的值相加就得到线性地址;
    Linux中的分段
    • 分段可以给每一个进程分配不同的线性地址空间;
    • 分页可以把同一线性地址空间映射到不同的物理空间;
    • 与分段相比, Linux更喜欢分页;
      • 当所有进程使用相同的段寄存器值时, 内存管理变得更简单, 也就是说他们能共享同样的一组线性地址;
      • RISC对段的支持很有限;
      • 用户代码段和用户数据段, 内核代码段和内核数据段;
    • Linux GDT: 单处理器只有一个GDT表, 而多处理器系统中每个CPU对应一个GDT, 放在cpu_gdt_table数组中;
    • Linux LDT: 大多数用户态下的Linux程序不使用局部描述符表, 这样内核就定义了一个缺省的LDT供大多数进程共享, 缺省的局部描述符表挡在default_ldt数组中;
    硬件中的分页
    • 分页单元把线性地址(虚拟地址)转换成物理地址;
      • 其中的一个关键人物就是把所请求的访问类型与线性地址的访问权限相比较, 如果这次内存访问是无效的, 就会产生一个缺页异常;
    • 为了效率起见, 线性地址呗分成以固定长度为单位的组, 称为页(page);
      • 页内部的连续线性地址被映射成连续的物理地址;
      • 内核可以指定一个页的物理地址和其存取权限, 而不用指定页所包含的全部线性地址的存取权限;
      • 一般情况下, 页即指一组线性地址, 又包含在这组地址中的数据;
    • 分页单元把所有的RAM分成固定长度的页框(page frame, 也叫作物理页);
      • 每个页框包含一个页, 也就是说一个页框的长度与一个页的长度一致;
      • 页框是主存的一部分, 也就是一个真实的存储区域;
      • 区分一页和一个页框是很重要得事情: 页只是一个数据块(是针对虚拟地址或者是线性地址来讲的), 页框可以理解为固定大小的物理内存地址, 用于存放页中的数据块;
    • 把线性地址映射到物理地址的数据结构称为页表(page table);
      • 页表存放在主存中, 并在启用分页单元之前必须有内核对页表进行适当的初始化;
      • cr0寄存器的PG标志位启动;
    常规分页
    • 32位的线性地址被分为3个域: directory(目录), table(页表), offset(偏移量);
      • 每一步都基于一种转换表, 页目录表(page directory), 页表(page table)
    • 物理地址扩展(PAE)分页机制: 页的大小可以改变;
    64位系统中的分页
    • 64位系统现在一般使用四级页表结构进行分页;
    • 引入硬件高速缓存(hardware cache memory): 硬件高速缓存是基于注明的局部性原理(locality principle), 既适用于程序结构, 又适用于数据结构;
    • 高速缓存内存插在分页单元和主内存之间, 它包含一个依那件高速缓存(hardware cache memory) 和 一个高速缓存控制器(cache controller);
    • 除了通过硬件高速缓存之外, 0xx86处理器还包括了另一个称为转换后援缓冲器或TLB(translation lookaside buffer)的高速缓存用于加快线性地址的转换;
      • 每个CPU都拥有一个自己的TLB, 这叫做该CPU的本地TLB
      • CPU的cr3寄存器被修改时, 硬件自动使本地TLB中的所有项都无效;
    • 4级分页模式中的4种页表:
      • 页全局目录(page global directory, PGD);
      • 页上级目录(page upper directory, PUD);
      • 页中间目录(page middle directory, PMD);
      • 页表(page table);
    • 每个进程都有自己的页全局目录和自己的页表集;
      • 进程切换时, Linux把cr3控制寄存器的内存保存在前一个执行进程的描述符中, 然后把下一个要执行的进程描述符的值转入到cr3寄存器中, 使分页单元指向正确的表项;
    • 从0x0000 0000 到0xbfff ffff的线性地址, 无论是进程运行在用户态还是内核态, 都可以寻址; 从0xc000 0000到0xffff ffff的线性地址, 只有在内核态的进程才能寻址;

    转载于:https://www.cnblogs.com/longjiang-uestc/p/9626146.html

    展开全文
  • 1. 内存寻址概述 1.1 图灵机 内存寻址的历史某种程度上来说就是现代计算机的历史。从最早的图灵机说起。如下图: 输入,输出,状态转移函数是图灵机的三要素,图灵机通过纸带完成内存寻址。 图灵机是现代计算机的...

    1. 内存寻址概述

    1.1 图灵机

    • 内存寻址的历史某种程度上来说就是现代计算机的历史。从最早的图灵机说起。如下图:
      在这里插入图片描述
    • 输入,输出,状态转移函数是图灵机的三要素,图灵机通过纸带完成内存寻址。
    • 图灵机是现代计算机的鼻祖。

    1.2 冯诺依曼体系结构

    在这里插入图片描述

    • 冯诺依曼体系核心思想:数据连续存储和选择读取思想。
    • 计算机背后的核心问题之一,就是如何有效的进行内存寻找,因为所以数据运算的前提都是需要从内存中取得数据。冯诺依曼体系给出了一种解决方案。

    1.3 CPU体系结构关系图

    在这里插入图片描述

    1.4 x86架构不同内存寻址的时期

    1.4.1 原始时期——>4位寻址

    在这里插入图片描述

    • 这是由intel在1971年推出的4bit的处理器,这里不多做介绍

    1.4.2 石器时期——>8位寻址

    在这里插入图片描述

    • intel8080是intel在1974推出的一款地址总线16bit,数据总线8bit的处理器,当时还没有段的概念,访问内存必须给出绝对地址,且重定位也不方便。

    1.4.3 青铜时期——>16位寻址(段概念引入)

    在这里插入图片描述

    • Intel8086是Intel在1978年推出的16bit的处理器,这个时候就引入了段的概念。
    • 由于8086需要寻址范围为1M所以其地址总线为20bit,而数据总线只有16bit所以其需要将1M大的空间分为数个64kB的段来管理。
    • 段描述了一块有限的内存区域,区域的起始位置存在专门的寄存器,也就是段寄存器中。
      在这里插入图片描述

    1.4.3.1 8086的寻址方式

    • 8086,如何通过16bit的地址寻址到1M的地址空间如图
      在这里插入图片描述
    • 8086的寻址过程其实就是将16位的段地址左移4位后与16位段偏移地址相加得到了20位的内存地址。也就是从16位内存地址到20位实际地址的转换,或者叫“映射”。这种模式也叫“实模式”。

    1.4.4 白银时期——>24位寻址(保护模式的引入)

    在这里插入图片描述

    • intel80286是Intel1982年推出的一款内部和外部数据总线皆为16位,地址总线24位,可寻址16MB内存芯片。80286的推出是实模式和保护模式CPU分水岭。
    • 此时引用了保护模式,cpu不在能直接访问段寄存器获得段的起始地址,而是需要通过额外的转换和检查。

    1.4.5 黄金时期——>32,64位寻址

    • inteli386是一个32位的cpu,其寻址能力达到4GB。
    • intel在段机制的基础上增加保护模式,使段寄存器虽然还是16位但是在保护模式下,它的段范围不再受限于64K,可以达到4GB。
    • 自i386推出后,后续cpu无论是32位还是64位都是在现有的基础上改进和加强,并无本质区别,所以i386以后的cpu被统称为x86架构。

    2. 实模式和保护模式

    2.1 实模式和保护模式寄存器对比

    在这里插入图片描述

    • 可以看出实模式和保护模式在寄存器上有很大的差异。
    • 在状态和控制寄存器中,有用于分页的寄存器cr0-cr3。

    2.2 保护模式下的页表寄存器

    在这里插入图片描述

    • 页表寄存器有CR0-CR3这里主要介绍CR0寄存器。
    • CR0包含了6个预定义的标志,这里介绍内核中用到的0位和31位。
    • 0位是保护允许位PE(protedted enable)主要是用于启动保护模式。
    • 31位是分页允许位(paging enable),表示芯片上的分页部件允许工作。
    • PG位和PE位比较可以很容易得出下表:
    PG PE 方式
    0 0 实模式, 8080操作
    0 1 保护模式, 但不允许分页
    1 0 出错
    1 1 允许分页的保护模式

    3. 问题

    3.1 为什么要引入保护模式?

    • 因为随着计算机不断发展,人们必将不再满足于,CPU只跑一个程序。这不可避免的就会出现两个程序,地址冲突的问题。这时可以将内存地址抽象化的保护模式方案就应运而生啦,程序员不需要在关心地址冲突的问题,而是交个系统管理。

    3.2 保护模式到底保护什么?

    • 内存保护
      根据上述详细的解析,我们可以知道,保护模式针对内存的保护主要有以下几方面:

      1. 分段、分页将内存切分,让每个进程独有内存空间,限定和保护整个物理内存
      2. 通过分段机制实现线性地址对物理地址的隐藏,通过分页机制实现虚拟地址对物理地址的隐藏,他们都实现了对物理地址的保护
      3. 通过段描述符、页表项属性的描述,提供了不同划分级别下内存块的属性保护
      4. 通过特权级与栈切换,实现了不同层级程序切换时的保护
        保护模式下中断描述附表的引入,让中断的切换和处理也被保护起来,包括中断处理程序使用的内存、特权级等
    • IO 的保护

      1. 通过 eflags 上的 IOPL 特权级与 TSS 指向的 IO 位图,IO 敏感操作也具有了严格的权限限制

      2. IO 端口被保护了起来,不同特权级的程序能使用的 IO 端口不同,不同一个特权级内,不同的进程能够使用的 IO 端口也不同,这样就实现了最细粒度的 IO 保护

    3.3 为什么能达到保护这些对象的目的?

    • 在保护模式下,内存以4Kb为粒度称为页,每个页表项都有自己的属性,用来达到保护对象的目的。
    • 此外保护模式下,还有特权级的概念,并规定低特权级不能访问高特权级,而高特权级可以访问低特权级。

    4.参考文献

    展开全文
  • 寻址空间与内存寻址

    2020-05-06 01:51:30
    寻址空间一般指的是CPU对于内存寻址的能力。通俗地说,就是能最多用到多少内存的一个问题。数据在存储器(RAM)中存放是有规律的 ,CPU在运算的时候需要把数据提取出来就需要知道数据存放在哪里 ,这时候就需要...
  • 内存寻址 本部分主要记录内存寻址这部分内容: CPU与Mem之间是如何连接的? 程序使用内存(virtual mem)与物理内存之间经过怎样的转换? 逻辑地址到线性地址的转换; 线性地址到物理地址的转换; Cache和MMU的...
  • 内存寻址原理

    2017-07-21 11:33:07
    在做网络安全事件分析的时候,都会遇到内存寻址的知识,例如上次跟大家分享的《 空指针漏洞防护技术》,就涉及到非法访问内存地址的问题。如果这个坎儿迈不过去,你就会迷失在代码中,更无从分析了。今天绿盟科技的...
  • linux内存寻址

    2017-03-26 16:24:17
    计算机内存寻址 计算机管理内存的基本方式有两种:段式管理和页式管理。而在使用80x86微处理器时,内存地址分为三个不同的地址:逻辑地址,线性地址,物理地址。他们之间有什么关系,内存是如何寻址,本文主要介绍...
  • 内存寻址优化

    千次阅读 2016-04-29 15:21:30
    内存寻址的简单优化问题描述: 在程序中,使用malloc或new创建一块内存用来存放二维或多维数组,当需要对数组进行遍历或进行块操作时,就需要对内存进行寻址操作,在寻址时,不可避免的存在不连续取址操作。
  • linux 内存寻址

    2009-02-25 03:22:22
    linux 内存寻址讲解和分析,PPT文件,容易理解
  • 内存寻址方式

    千次阅读 2017-04-08 11:44:35
    实验三 内存寻址方式 一、实验目的 l 理解程序在访问内存单元时采用的各种寻址方式 l 学会基于字符的ASCII编码,进行大小写转换、简单加密等方法 l 学会用loop指令,结合寻址方式,编制单层和双层循环程序...
  • Linux内核之内存寻址

    2017-12-17 11:41:53
    内存寻址概要
  • 计算机内存寻址

    2016-07-21 08:43:23
    他们之间有什么关系,内存是如何寻址,本文主要介绍的就是内存寻址。 1、基本概念: cpu段式管理:段式管理的基本原理是指把一个程序分成若干个段(segment)进行存储,每个段都是一个逻辑实体(logical entity)...
  • 一、内存地址 对于80x86微处理器,我们需要区分以下地址: 逻辑地址:这种寻址方式是x86才有的著名的分段...物理地址:用于内存芯片级别内存寻址。他们从微处理器的地址引脚发送到内存总线上的电信号相对对应。 ...
  • Linux 内存寻址之分段机制 前言 分段到底是怎么回事? 实模式的诞生(16位处理器及寻址) 保护模式的诞生(32位处理器及寻址) IA32的内存寻址机制 寻址硬件 IA32的三种地址 MMU地址转化过程 IA32的段...
  • 8086处理器的内存寻址方式主要分三种 寄存器寻址 立即寻址 内存寻址(也有书叫存储器操作数寻址) 寄存器寻址 最简单的寻址方式就是寄存器寻址。也就是指程序执行时,操作的数就存放在寄存器当中,可以直接从...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,168
精华内容 3,267
关键字:

内存寻址