鱼C论坛

 找回密码
 立即注册
查看: 1655|回复: 9

什么是内存地址映射?

[复制链接]
发表于 2014-4-2 20:51:53 | 显示全部楼层 |阅读模式
10鱼币
希望讲的通俗点

最佳答案

查看完整内容

现代操作系统如Linux和Windows都是采用内存保护模式来管理内存。 普通用户程序中的地址是如何转换到内存上的物理地址的? IA-32架构的CPU规定地址映射过程是: 逻辑地址---->> 线性地址 ------->> 物理地址 Windows对于内存的管理,采取的是分页机制,分页大小为4K,每个进程都占有一定的虚拟地址空间,在这个机制下,这个空间一部分被映射到物理内存,一部分映射到虚拟内存(存在于硬盘上的一个或多个空间),还有一部分 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-2 20:51:54 | 显示全部楼层
现代操作系统如Linux和Windows都是采用内存保护模式来管理内存。
普通用户程序中的地址是如何转换到内存上的物理地址的?
IA-32架构的CPU规定地址映射过程是:
逻辑地址---->>  线性地址  ------->>  物理地址

Windows对于内存的管理,采取的是分页机制,分页大小为4K,每个进程都占有一定的虚拟地址空间,在这个机制下,这个空间一部分被映射到物理内存,一部分映射到虚拟内存(存在于硬盘上的一个或多个空间),还有一部分则可能什么也没有映射。同时,在CPU中,会设置一个“分页标志位”,如果CPU在运行指令时发现这个分页标志被设置,则会根据页目录和页表中的对应关系,将指令中的虚拟地址转换为实际的物理地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-2 21:15:36 | 显示全部楼层
http://wenwen.sogou.com/z/q181670447.htm
内存物理地址为A,即地址A
而物理地址A得地址代码又需要内存来存放,我们设地址A存的地址为地址B
所谓映射就是把存地址A代码的地址B由地址C来来指向地址B,也就是说通过C来间接的指向实际地址A
这就好比一个储藏库为A,地址代码为1111,我把这个地址代码放到B处(B里面放上A的地址代码1111),而B的地址为10000,我在把B的地址10000放到C中(01010),这样C就是对B的映射!

好吧。。我来个简单的。。。
int A = 3;
int *B = &A;
int *C = &B; //注意。。不要以为类型错了。。B虽然是一个int*类型。。但是B也是存放在一个地址的。。而这个地址在32位就是4字节。。也就是int 大小
C就是对B的映射

评分

参与人数 1鱼币 +5 贡献 +3 收起 理由
隨鈊乄鎍慾 + 5 + 3 sorry!sorry!补上好评如何?

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-2 21:32:07 | 显示全部楼层
在Win32中,每个进程有自己的地址空间,一个进程不能轻易地访问另一个进程地址空间中的数据,所以不能像16位Windows那样做。Win32系统允许多个进程(运行在同一计算机上)使用内存映射文件来共享数据。实际上,其他共享和传送数据的技术,诸如使用SendMessage或者PostMessage,都在内部使用了内存映射文件。
   
这种数据共享是让两个或多个进程映射同一文件映射对象的视图,即它们在共享同一物理存储页。这样,当一个进程向内存映射文件的一个视图写入数据时,其他的进程立即在自己的视图中看到变化。但要注意,对文件映射对象要使用同一名字。
   
以下是一段使用内存映射文件的代码:
   
创建:
   
HANDLE     s_hFileMap     =    CreateFileMapping((HANDLE)0XFFFFFFFF,NULL,PAGE_READWRITE,     0,    4*1024,_TEXT( "MyCustShareData"));
(此函数寻找一个名字为 "MyCustShareData "的内存映射文件,不存在则创建,存在则返回已有的句柄,所以当返回值不为空的话,还须检查GetLastError,如果得到ERROR_ALREADY_EXISTS,则表明该名字的内存映射文件已经存在,并未创建成功)
   
读写:

HANDLE     hFile     =    OpenFileMapping(FILE_MAP_READ     |     FILE_MAP_WRITE,    FALSE,     _TEXT( "MyCustShareData "));//最后一个参数为名字,必须与创建的相同
   
if(hFile     !=     NULL)
{
                LPVOID    lpView     =         MapViewOfFile(hFile,    FILE_MAP_READ     |     FILE_MAP_WRITE,    0,     0,     0);//将内存映射文件的一个视图映射到当前的地址空间
                if     ((int    *)lpView     !=     NULL)     
                {
    int     sheardata     =    (int*)lpview;     //读     
                                   (int     *)lpview    =     88;     //写
                }
               UpmapViewOfFile((LPVOID)     lpview);
}
CloseHandle(hFile);

其中MapViewOfFile的原型如下所示:
LPVOID   MapViewOfFile(
    HANDLE   hFileMappingObject,       //   映射文件对象的句柄
    DWORD   dwDesiredAccess,              //   访问模式
    DWORD   dwFileOffsetHigh,            //   位移的高位
    DWORD   dwFileOffsetLow,              //   位移的低位(与前一个参数一起构成64位的位移量)
    SIZE_T   dwNumberOfBytesToMap     //   映射量(单位为Byte,当设为0时表示映射整个文件)
);

您所提到的mapviewoffileEx函数的原型如下所示:
LPVOID   MapViewOfFileEx(
    HANDLE   hFileMappingObject,      
    DWORD   dwDesiredAccess,              
    DWORD   dwFileOffsetHigh,            
    DWORD   dwFileOffsetLow,              
    SIZE_T   dwNumberOfBytesToMap,   
    LPVOID   lpBaseAddress                  
);

其中前五个参数的含义同上,第六个参数给出一个调用映射文件的进程的地址,要求文件映射从该地址开始。这个值必须是一个系统内存分配的最小粒度的整数倍,否则此函数调用失败。要获得内存分配的粒度,可以调用GetSystemInfo函数。如果指定的内存地址没有足够的空间,则函数也失败。

如果此参数的值设为NULL,则操作系统选择从何地址开始进行文件映射,这样,函数的功能与MapViewOfFile相同。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-4-2 22:20:58 | 显示全部楼层

首先向青莲前辈问好(现在不说你是老人家了 >_< )!感谢你的回答。你讲得很通简单易懂但是我还是有点不清楚我是不是可以这样理解:C和B的关系就是C是一个指向指针的指针具体指向的是B也就是映射的B 对吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-3 12:24:58 | 显示全部楼层
隨鈊乄鎍慾 发表于 2014-4-2 22:20
首先向青莲前辈问好(现在不说你是老人家了 >_< )!感谢你的回答。你讲得很通简单易懂但是我还是有点不清 ...

对啊。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-3 17:58:45 | 显示全部楼层
嗯嗯!正如楼上所说的,补充一下,这个分页标志位是由控制寄存器CR0决定的,控制寄存器CR0中的位0用PE标记,位31用PG标记,这两个位控制分段和分页管理机制的操作,所以把它们称为保护控制位。PE控制分段管理机制。 PE=0,处理器运行于实模式;PE=1,处理器运行于保护方式。PG控制分页管理机制。PG=0,禁用分页管理机制,此时分段管理机制产生的线性地址直接作为物理地址使 用;PG=1,启用分页管理机制,此时线性地址经分页管理机制转换位物理地址。由此可知,如果要启用分页机制,那么PE和PG标志都要置位。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-4-3 20:06:41 | 显示全部楼层
青玄 发表于 2014-4-3 17:58
嗯嗯!正如楼上所说的,补充一下,这个分页标志位是由控制寄存器CR0决定的,控制寄存器CR0中的位0用PE标记, ...

感谢回答.............
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-4-3 20:07:35 | 显示全部楼层
福禄娃娃 发表于 2014-4-3 17:34
现代操作系统如Linux和Windows都是采用内存保护模式来管理内存。
普通用户程序中的地址是如何转换到内存上 ...

非常感谢你的回答.........
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-5 18:19:07 | 显示全部楼层
额。。。。。。。。←_←。。。。。。。不是说通俗点么。。。。。。。居然没选我。。。。。。。伤心。。。。。:cry
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-26 23:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表