所以我正在玩Olly调试器,嗅探我能找到的关于windows的内容,然后按下M按钮,它弹出了内存映射窗口。所以我搜索了一些关于这个主题的文章,我发现我实际上可以写到64K以上的地址,我试过并且很好..为什么它不起作用。关于那些较低的2GB空间:
为什么会出现这些差距?例如,有0x10000-0x1FFFF R / Wable空间然后没有128K,然后是一些可读空间。我的意思是这已经被正确分页了,所以在物理空间中是否存在过去的事情并不重要(不要提到0x20000-0x40000应该完全没有r / w),为什么有人决定不如此随机使用一些地址空间? 很可能我只是感到困惑,因为在olly调试器的内存映射中,很多行都是空的,其中列是'Contains'。是否有一些参考资料我可以从olly那里反对这个记忆图,并找出哪个空间有什么目的,因此是否被这样分页?
假设我真的不想搞任何关于内存管理的问题,是否可以使用较低内存而不是使用堆来编写Windows程序,还是会遇到一些问题?
感谢您阅读此问题。
修改
啊here我们使用0x10000处的内容,这也可能是该页面可写的原因。
答案 0 :(得分:3)
您似乎没有焦点问题,因此很难提供有价值的答案。但是,您似乎暗示了一个问题 Windows如何映射用户空间内存?
首先,低的虚拟内存空间 - 从零到64K或更多 - 未被分配以捕获基于NULL的指针解除引用。这些是我们想要立即了解的常见编程错误。如果发生这种情况,该程序几乎肯定会终止。通过将此空间保留为未映射,将发生Windows等效的SEGFAULT。非常有用。
通常,接下来分配代码和常量空间。一旦程序开始运行,通常不需要更改此空间,因此它被设置为只读,并且其中的一部分被标记为可执行 - 通常是第一部分,可以是99%的空间。如果存在共享代码库,则这些代码库在主代码(通常)之后映射,通常具有小间隙,以便库代码段是页面对齐的(可能是4K,可能是64K或更大),以实现有效的内存管理寄存器使用。几乎不需要节省虚拟内存空间。
之后是数据空间。这可以是初始化的内存,也可以是未初始化的。这一切都必须是可读写的。它需要在它上面保留空间,以便它可以增加堆空间的增长。
以上数据空间的方式是堆栈空间。它必须是可读写的,并且位于之下,因此它可以增长。所有现代CPU堆栈都会向低内存增长。
堆栈上方是系统空间。
如果进程请求访问共享内存(与其他进程),则映射窗口的大小决定了它可以适合的内存映射中的位置。映射太靠近堆增长的位置是一个问题,而且太接近潜在的堆栈增长也是一个问题。幸运的是,相当简单的放置算法可以解决绝大多数程序的问题。只需考虑各种需求,您就可以弄清楚操作系统为什么会这样做。
答案 1 :(得分:1)
并非所有内存都可供应用程序使用。例如,某些类型的硬件需要内存,因此系统(BIOS或OS)将分配一块物理内存并将其留给硬件来管理自身。该内存可能无法直接读取(或写入),因为执行此类操作会影响硬件。硬件本身可能对其可以使用的内存范围有自己的限制。
如果您在Windows中,则无法写入任意内存位置 - 操作系统不会让您(至少在用户模式下)并且无论如何都会分页内存,因此您认为自己的地址是查看(虚拟地址)与实际物理内存地址不匹配。
通常,您应该只读取和写入操作系统已请求并分配给您的内存。