自定义堆/内存分配范围

时间:2017-08-03 05:07:52

标签: c memory-management malloc low-level

我正在C(用GCC)和Linux下的NASM编写64位应​​用程序。

有没有办法指定,我希望我的堆和堆栈位于何处。具体来说,我希望我的所有malloc数据都在任何地方,范围为0x00000000-0x7FFFFFFF。这可以在编译时,链接或运行时,通过C代码或其他方式完成。这没关系。

如果无法做到这一点,请解释原因。

P.S。对于那些感兴趣的人,我在做什么:

  

我正在编写的程序是用C编写的。在运行时它会生成NASM代码,编译它并动态链接到已经运行的程序。这是极端优化所必需的,因为该代码将运行数千次 - 如果不是数十亿次,并且在编译时是未知的。所以我需要0x00000000-0x7FFFFFFF地址的原因是因为它们适合汇编代码中的immediates。如果我不需要单独加载地址,我只需要大约一半的内存访问量并增加位置。

1 个答案:

答案 0 :(得分:2)

对于Linux,获取任何虚拟地址范围的标准方法是使用mmap(2)功能。

您可以指定起始虚拟地址和大小。如果该地址尚未使用且未通过先前调用(或内核)保留,则您将可以访问该虚拟地址。

可以通过将返回值与您传递的起始地址进行比较来检查此调用是否成功。如果调用失败,函数将返回NULL

通常mmap用于将虚拟地址映射到文件描述符。但是这种映射必须通过RAM上的物理页面进行。由于应用程序无法直接访问磁盘。

由于您不想要任何文件支持,因此您可以使用MAP_ANONYMOUS调用中的mmap标记(同时将-1作为fd传递)。

这是人工页面相关部分的摘录 -

  

MAP_ANONYMOUS

     

任何文件都不支持映射;它的内容是                 初始化为零。 fd参数被忽略;然而,                 如果MAP_ANONYMOUS(或。),某些实现要求fd为-1                 指定MAP_ANON),便携式应用程序应该                 确保这一点。 offset参数应为零。指某东西的用途                 支持MAP_ANONYMOUS与MAP_SHARED一起使用                 Linux仅从内核2.4开始。