【问题标题】:anything specific about the addresses (0x40000000, 0x80000000 and 0xBF000000)有关地址的任何具体信息(0x40000000、0x80000000 和 0xBF000000)
【发布时间】:2012-04-17 04:00:10
【问题描述】:

我遇到了一个示例 gdbinit 文件,其中包含以下语句。谁能告诉我地址​​(0x40000000、0x80000000 和 0xBF000000)有什么特别之处?为什么再次检查他们让我知道有效或无效的地址?

define dd
if ( ($arg0 & 0x40000000) || ($arg0 & 0x08000000) || ($arg0 & 0xBF000000) )
set $data_addr=$arg0
ddump 0x10 $arg0
else
printf "Invalid address: %08X\n", $arg0
end
end

进一步,以下针对相同地址的检查如何再次告诉我为数据地址选择哪个寄存器?

define datawin
if ( ($esi & 0x40000000) || ($esi & 0x08000000) || ($esi & 0xBF000000) )
set $data_addr=$esi
else
if ( ($edi & 0x40000000) || ($edi & 0x08000000) || ($edi & 0xBF000000) )
set $data_addr=$edi
else
if ( ($eax & 0x40000000) || ($eax & 0x08000000) || ($eax & 0xBF000000) )
set $data_addr=$eax
else
set $data_addr=$esp
end

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: c memory memory-management operating-system gdb


    【解决方案1】:

    在具有 MMU 功能的 CPU 上运行的大多数现代操作系统都为进程提供了一个划分为特定区域的虚拟内存模型。一般来说,低地址属于进程,高地址属于操作系统。在这些之间,有堆栈空间。在您的情况下,它是一个 32 位系统。第一部分检查地址的有效性(但此检查不保证给定地址的可访问性),第二部分只使用给定的寄存器...

    【讨论】:

    • 感谢您的回答。你能告诉我当你说一般情况下,低地址属于进程,高地址属于操作系统。当你说第一部分时,请告诉我检查地址的有效性(但此检查不保证给定地址的可访问性) 给定检查有什么问题。是否可以对其进行改进以进行有效检查。你也可以给我一些链接,也让我知道一些可以详细告诉我内存映射的书籍。非常感谢。
    • 由于历史和现实原因,下位地址属于进程。在没有 VM 概念的时候,从 0x0 开始内存映射是非常符合逻辑的。此 VM 地址不是物理地址,因此它可以位于物理内存中的任何位置。此外,虚拟机垃圾收集器在地址越低时性能越好。地址的有效性意味着该进程是否可以访问该特定 VM 地址。您不能访问超出程序中断的地址,还有“const”。阅读 :: en.wikipedia.org/wiki/Sbrk , internals.com/articles/protmode/protmode.htm
    • 感谢您的信息。你能告诉我一些深入讲述内存映射的书名吗?再次感谢。
    • 任何最近的操作系统内核书籍都应该解释一下,抱歉我没有推荐。在线资源可能就足够了。 Jhonnash 指出了一些有用的链接...
    【解决方案2】:

    在大多数板上 在这种情况下,0x00000000 到 0x00ffffff RAM 被映射,Flash 0x40000000 到 0x407fffff 被映射。

    该特定页面存在很多问题 - 恕我直言,它大多已过时(对于 80386,它可能不太不正确)。 具体来说: - EBDA 大小以及视频 ROM 和 BIOS 的大小都不是固定大小。有些电脑是“无头”的,没有视频(或视频 ROM)。

    • 视频 ROM 和 BIOS 之间的区域从未包含“无”。它一直为其他“设备特定 ROM”(SCSI BIOS、以太网引导 ROM 等)保留,对于某些系统,该区域可能包含可用 RAM(某些操作系统,如 Windows 95,实际上扫描该区域并使用在其中找到的任何 RAM它)。

    • 对于较旧的计算机(可能还有最近的计算机,包括一些新计算机,如果为它配置了 BIOS),15 MB 到 16 MB 之间的区域是一个“内存漏洞”,曾经(并且可能仍在)使用用于内存映射 I/O 的旧 ISA 设备。这个区域最常被 ISA SVGA 卡使用,但任何 ISA 卡(甚至是插入全新计算机的旧 ISA 卡)都可以使用。

    • NVRAM 和 ACPI 不使用高于 0xFEC00000 的内存,并且永远不会使用。而是使用 RAM 顶部的内存(例如,对于具有 256 MB RAM 的计算机来说,内存刚好低于 0x10000000)。

    • 通常有一个低于 0xFEC00000 的区域用于内存映射的 PCI/AGP 设备(例如视频线性帧缓冲区)。该区域的大小取决于 BIOS 和主板(通常从 0xC0000000 或 0xE0000000 开始)。这意味着对于具有 4 GB RAM 的计算机,“32 位”操作系统将只能使用 3 GB 或 3.5 GB。大多数“好”的主板会将备用 RAM 映射到 4 GB 以上(操作系统需要使用 PAE、PSE36 或长模式来访问它)。便宜的主板可能只会浪费这些内存。

    • 从 0xFEC00000 到 BIOS 底部的区域(实际上略低于 4 GB - 由于芯片组技巧,它的全部或部分似乎低于 1 MB)主要保留给本地 APIC 和 I/ O APIC(如果有)。

    • 在较新的计算机上,RAM 可能超过 4 GB。这还不是很常见,但Vista 也还没有正式发布。

    • 对于服务器,事情可能更加复杂。 NUMA 是一个问题(包括简单的“双插槽”AMD 系统),它可能会导致 RAM 配置在存储区中(例如,0x00000000 处为 512 MB,0x80000000 处为 512 MB,中间有一个大孔)。此外,一些服务器支持“热插拔”RAM 区域(通常高于“启动时安装的 RAM”,通常也高于 4 GB)。

    http://forum.osdev.org/viewtopic.php?t=11391

    http://books.google.co.in/books?id=xnFdWfJAK9wC&pg=PT289&lpg=PT289&dq=on+hard+disk+addresses+0x40000000&source=bl&ots=GFQJQ5R_-Z&sig=VchcoPWMeIE4E-Vzom1lmUxxJSg&hl=en&sa=X&ei=jvx6T4CiL8amrAeVzbiEAg&sqi=2&ved=0CEsQ6AEwAQ#v=onepage&q=on%20hard%20disk%20addresses%200x40000000&f=false

    所以,我可以说这些是 Linux 操作系统对内存的限制。我们无法从 0x00000000 获取基地址,因为它被映射到某个限制。基地址 0x40000000 通常是操作系统代码的开始,同样我可以说基地址 0xBF000000 是操作系统代码的限制。

    【讨论】:

    • 我无法在您的 cmets 中获得一些东西。此外,它似乎特定于某些董事会。你也可以给我一些链接,也让我知道一些可以详细告诉我内存映射的书籍。非常感谢。
    【解决方案3】:

    这是针对 Linux 的。您的标题中有一个地址错误,不是 0x80000000 而是 0x8000000。

    Linux 程序通常在 0x8210000 (iirc) 加载。该范围适用于您的代码本身。

    堆栈默认为 0xBFFF????。这是第二个范围。

    第三个范围可能是可写数据部分的开始,或者是加载库的位置。

    检查似乎写得不好,但没有检查二进制 AND 最终返回的内容,因此带有“0xBF000000”的 and 将返回 true 以获得比它应该的更多的地址。

    [编辑]您问题的第二部分,如果 esi/edi/eax 中的任何一个在该区域中包含一个数字,它很可能指向您数据区域中的某个地方。

    【讨论】:

    • 感谢您指出标题中的错误。当您说 Linux 程序通常在 0x8210000 (iirc) 加载时,您能多说一点吗? 什么是 iirc,通常是什么加载方式。它会随着某些因素而改变吗?还有什么???在此处指出 0xBFFF????* 。支票可以写得更好吗? 您问题的第二部分.. 在这个区域中 这是从内存中数据段的开头转储十六进制数据的检查。你也可以给我一些链接,也让我知道一些可以详细告诉我内存映射的书籍。非常感谢。
    • wiki.osdev.org/Expanded_Main_Page 包含很多关于操作系统内部的一般信息,其中包括内存映射。 Linux上有asm.sourceforge.net/articles/startup.html,这表明加载程序的不是8210000而是8048000,并且堆栈在0xBFFFFFFF处结束。问号是“任意数字”。如果您使用 ASLR - 地址空间布局随机化,这些位置可能会发生变化,这会减少一些黑客尝试成功的机会。
    【解决方案4】:

    可以查看Mapping的过程:

    $ pmap pid
    $ pmap 3724
    

    书籍:

    “了解 Linux 内核”9.3。记忆区; 16.2.内存映射 《理解Linux虚拟内存管理器》4.4 内存区域

    链接:

    http://www.scs.ch/~frey/linux/memorymap.html
    http://www.linuxdoc.org/HOWTO/KernelAnalysis-HOWTO-7.html
    http://linuxdevcenter.com/pub/a/linux/2006/11/30/linux-out-of-memory.html
    http://www.linux-tutorial.info/modules.php?name=MContent&pageid=260
    http://www.syslinux.org/wiki/index.php/Memory_Map_(General)
    

    由于我不知道您的代码在什么类型的系统上内存不足;你在用什么这么精确的定义很难给出。在上面的答案中,我给出了来自“Linux kernel Programming - Robert Love”的板映射示例的详细信息,以及有关各种操作系统(linux)和硬件的一些详细信息,这些都有一些限制。因此,很难判断内存限制是多少。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-06
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多