(二)内存寻址

本文讲述linux在X86平台上的分段和分页机制

MMU(内存控制单元)通过分段单元的硬件电路将逻辑地址转换成线性地址,再通过分页单元的硬件电路把线性地址转换为物理地址:

逻辑地址:包含在机器指令语言指令中用来指定一个操作数或一条指令的地址。每个进程都有自己的代码段,数据段,逻辑地址就是相对于代码段或数据段的偏移地址。

线性地址:程序代码产生逻辑地址,逻辑地址经过分段单元的硬件电路准换为线性地址。线性地址的范围一般与CPU的位数相关,如果是32为的CPU,则可以表达高达4G的线性地址。

物理地址:用于物理内存芯片的内存单元寻址。它的范围与地址总线的位数相关。

X86的硬件分段:

一个逻辑地址分为两部分组成:段标识符和指定段内相对地址的偏移量。

处理器提供6个段寄存器,CS,SS,DS,ES,FS,GS;

段描述符:8个字节;用来存放段起始地址,段大小,存储权限等。存储在GDT或LDT中。

段选择符(段标识符):16位,用来寻找段描述符,存放于段寄存器中。

分段流程:将逻辑地址指定的段标识符装载在段寄存器中,由段标识符指定段描述符的起始地址,在段描述中找到相应段的段起始地址,将段起始地址左移N(N=地址总线位数-CPU位数),然后与逻辑地址指定的段内偏移量相加,得到线性地址。

linux的分段:

linux以非常有限的方式使用分段,只有在X86机构下才使用分段(一些体系结构对分段支持很有限,尤其是RISC)。

运行在用户态的linux进程都使用一对相同的段来对指令和数据寻址:用户代码段和用户数据段;运行在内核态的所有linux进程都使用一对相同的段对指令和数据寻址:内核代码段和内核数据段。他们的段起始地址都是0X0,则在linux下逻辑地址和线性地址是一致的,即逻辑地址的偏移量字段的值和相应的线性地址的值总是一致的。

X86的硬件分页:

分页单元将线性地址转换成物理地址。

为了效率起见,线性地址被分成以固定长度为单位的组,称为页。页内部的线性地址被映射到连续的物理地址中。分页单元把所有的RAM分成固定长度的页框。

把线性地址映射到物理地址的数据结构称为页表。页表存放在主存中,并在启用分页单元之前必须有内核对页表进行适当的初始化。

常规分页:

从386开始,intel处理器的分页单元处理4KB的页。32位的线性地址被分成3个域:Directory(目录)最高10位:Table(页表)中间10位:Offset(偏移量)最低12位;线性地址的转换分两步完成,每一步都基于一种转换表,第一种转换表称为页目录表,第二种表称为页表;使用二级模式的目的在于减少每个进程页表所需的RAM数量。每个活动进程都有一个分配给它的页目录,在实际需要时分配页表,其页目录的物理地址存放在控制寄存器的cr3中,cr3与线性地址的dirctory字段决定页目录中的目录项,再通过线性地址的TABLE字段决定页表的表项,再配合OFFSET字段找到页框内物理地址。

扩展分页:

从pentiun开始,X86引入扩展分页,页框大小为4MB,扩展分页把大段连续的线性地址转换为响应的物理地址。内核则可以不用对中间页表转换。DIRECTIORY(10位):OFFSET(22位);

物理地址扩展分页机制:

处理器所支持的RAM容量受到连接到地址总线上的地址管脚数量限制。大型服务器需要大于4GB的RAM时,intel在它的处理器上把管脚从32增加到36位,引入物理地址扩展的分页机制将32位线性地址转换为36位物理地址。

64位系统的分页:

32位的系统采用2级分页机制,出于效率和RAM容量的考虑,64位系统采用额外的分页机制。使用的级别的数量取决于处理器的类型。

        linux 的分页:

linux采用了一种同时适用于32位和64位熊的普通分页模型,目前采用四级分页模型:页全局目录:页上级目录:页中间目录:页表。

页全局目录包含若干页上级目录的地址,页上级目录包含若干页中间级目录的地址,页中间级目录又包含若干页表的地址。每个页表项又指向夜歌页框。线性地址因此被分成了5个部分。

没有启动物理地址扩展的32位系统,linux采用2级模型:页全局目录和页表,页上级目录和页中间级目录全置0;

启用了物理地址扩展的32位系统使用3级页表。

64位系统使用三级还是四级分页取决于硬件对线性地址的划分。

时间: 2024-08-04 10:54:33

(二)内存寻址的相关文章

内存寻址二(分页)

硬件中的分页 概念 分页单元(paging unit)把线性地址转换成物理地址.其中一个关键任务是把所请求的访问类型与线性地址的访问权限相比较,如果这次内存访问时无效的,就产生一个缺页异常. 为了效率起见,线性地址被分成以固定长度为单位的组,称为页(page).页内部连续的线性地址被映射到连续的物理地址中.这样,内核可以指定一个页的物理地址和其存取权限,而不用指定页所包含的全部线性地址的存取权限.通常使用术语"页"既指一组线性地址,又指包含在这组地址中的数据. 分页单元把所有的RAM分

X64下MmIsAddressValid的逆向及内存寻址解析

标 题: [原创]X64下MmIsAddressValid的逆向及内存寻址解析 作 者: 普通朋友 时 间: 2015-10-21,20:03:52 链 接: http://bbs.pediy.com/showthread.php?t=205143 在内核编程时,经常会用到MmIsAddressValid来检测地址是否有效,结合之前学过的虚拟地址到物理地址之间的转化,所以发一篇对该函数的逆向以及代码还原,x86的资料论坛以及网络有很多了,所以这里楼主只谈一下Win7 x64下的MmIsAddre

内存寻址

当使用80x86微处理器时,我们必须区分三种地址: 1.逻辑地址(logical address) 包含在机器语言指令中用来指定一个操作数或者一条指令的地址.由一个段(segment)和偏移量(offset)组成. 2.线性地址(linear addres,也称虚拟地址 virtual address) 是一个32位无符号整型.是我们编程时接触到的都是这种. 3.物理地址(physical address) 用于内存芯片级内存单位元寻址. 内存控制单元(MMU)通过一种称为分段单元(segmen

Linux内存寻址

我会尽力以最简洁清晰的思路来写这篇文章. 所谓内存寻址也就是从写在指令里的地址,转化为实际物理地址的过程.因为操作系统要兼顾许多东西,所以也就变得复杂. 逻辑地址 → 线性地址 → 物理地址 逻辑地址 = 段 + 偏移量 因为:最开始cpu中的alu宽度只有16位,但地址总线宽度有20位.所以设置四个段寄存器:cs(指令),ds(数据),ss(堆栈),es(其它). 每个段寄存器16位,对应地址总线高16位.每条指令中的16位内部地址与某个段寄存器中内容相加,得到20位的实际地址. 上述的16位

Linux内存寻址之分段机制

http://blog.xiaohansong.com/2015/10/03/Linux内存寻址之分段机制/ .段的起始地址.段的长度等等,而在保护模式下则复杂一些.IA32将它们结合在一起用一个8字节的数表示,称为描述符 .IA32的一个通用的段描述符的结构从图可以看出,一个段描述符指出了段的32位基地址和20位段界限(即段长).这里我们只关注基地址和段界限,其他的属性略过. 段描述符表 各种各样的用户描述符和系统描述符,都放在对应的全局描述符表.局部描述符表和中断描述符表中.描述符表(即段表

Linux内存寻址之分页机制

http://blog.xiaohansong.com/2015/10/05/Linux内存寻址之分页机制/ 在上一篇文章Linux内存寻址之分段机制中,我们了解逻辑地址通过分段机制转换为线性地址的过程.下面,我们就来看看更加重要和复杂的分页机制. 分页机制在段机制之后进行,以完成线性-物理地址的转换过程.段机制把逻辑地址转换为线性地址,分页机制进一步把该线性地址再转换为物理地址. 硬件中的分页 分页机制由CR0中的PG位启用.如PG=1,启用分页机制,并使用本节要描述的机制,把线性地址转换为物

Linux内存管理学习笔记——内存寻址

最近开始想稍微深入一点地学习Linux内核,主要参考内容是<深入理解Linux内核>和<深入理解Linux内核架构>以及源码,经验有限,只能分析出有限的内容,看完这遍以后再更深入学习吧. 1,内存地址 逻辑地址:包含在机器语言中用来指定一个操作数或一条指令的地址. 线性地址:一个32位无符号数,用于直接映射物理地址 物理地址:片上引脚寻址级别的地址 2,逻辑地址->线性地址 2.1 段选择符与段寄存器 逻辑地址:段选择符(16位)+段内偏移(32位) index:在GDT或L

汇编第一节-寄存器与内存寻址

1. 内存寻址方式: 确定访问内存存储单元偏移地址方式,称为寻址方式. 名称 格式 直接寻址 [偏移量值] 寄存器简介寻址 [基址寄存器/变址寄存器] 寄存器相对寻址 [基址寄存器/变址寄存器+偏移量值] 基址变址寻址 [基址寄存器+变址寄存器] 相对基址变址寻址 [基址寄存器+变址寄存器+偏移量值] 2. 寄存器 普通寄存器:AX(AH,AL).BX(BH,BL).CX(CH,CL).DX(DH,DL).SP.BP.SI.DI 段寄存器:DS.SS.CS.ES 3.BX.SI.DI.BP寄存器

内核基础 - 寄存器与内存寻址(by quqi99)

作者:张华  发表于:2016-03-01 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 汇编 汇编编译器assembler编译目标代码二进制文件(nasm -f elf -g -F stabs *.asm),连接器linker(ld -o bin_file *.o)除了把目标代码组合成一个单个的块,还要确保模块以外的函数调用能够指向正确的内存引用(连接器必须建立一个索引,也就是符号表,里面

垃圾回收GC:.Net自己主动内存管理 上(二)内存算法

垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己主动内存管理 上(三)终结器 前言 .Net下的GC全然攻克了开发人员跟踪内存使用以及控制释放内存的窘态.然而,你或午想要理解GC是怎么工作的.此系列文章中将会解释内存资源是怎么被合理分配及管理的,并包括很具体的内在算法描写叙述.同一时候.还将讨论GC的内存清理流程及什么时清理,怎么样强制清理. 内