自定义堆/内存分配范围 [英] Custom heap/memory allocation ranges

查看:42
本文介绍了自定义堆/内存分配范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Linux下用C(带有GCC)和NASM编写一个64位应用程序.

I am writing a 64-bit application in C (with GCC) and NASM under Linux.

有没有一种方法可以指定堆和堆栈的放置位置.具体来说,我希望我所有分配的数据都在任意位置 ,范围为0x00000000-0x7FFFFFFF.这可以通过 C 代码或其他方式在编译时、链接或运行时完成.没关系.

Is there a way to specify, where I want my heap and stack to be located. Specifically, I want all my malloc'ed data to be anywhere in range 0x00000000-0x7FFFFFFF. This can be done at either compile time, linking or runtime, via C code or otherwise. It doesn't matter.

如果这不可能,请解释原因.

If this is not possible, please explain, why.

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

P.S. For those interested, what the heck I am doing:

我正在处理的程序是用C编写的.在运行时,它将生成NASM代码,对其进行编译,并动态链接到已运行的程序.这是极端优化所必需的,因为该代码将运行数千(如果不是十亿)次,并且在编译时未知.因此,我需要0x00000000-0x7FFFFFFF地址的原因是因为它们适合汇编代码中的立即数.如果不需要分别加载地址,则只需访问所需内存访问次数的一半即可,而且可以增加局部性.

The program I am working on is written in C. During runtime it generates NASM code, compiles it and dynamically links to the already running program. This is needed for extreme optimization, because that code will be run thousands-if-not-billions of times, and is not known at compile time. So the reason I need 0x00000000-0x7FFFFFFF addresses is because they fit in immediates in assembler code. If I don't need to load the addresses separately, I can just about half the number of memory accesses needed and increase locality.

推荐答案

对于Linux,获取任何虚拟地址范围的标准方法是使用

For Linux, the standard way of acquiring any Virtual Address range is using the mmap(2) function.

您可以指定起始虚拟地址和大小.如果该地址尚未使用,并且之前的调用(或内核)未保留该地址,则可以访问该虚拟地址.

You can specify the starting virtual address and the size. If the address is not already in use and it not reserved by prior calls (or by the kernel) you will get access to the virtual address.

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

The success of this call can be checked by comparing the return value to the start address you passed. If the call fails, the function returns NULL.

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

In general mmap is used to map virtual addresses to file descriptors. But this mapping has to happen through physical pages on the RAM. Since the applications cannot directly access the disk.

由于您不希望备份任何文件,因此可以在 mmap 调用中使用 MAP_ANONYMOUS 标志(也可以将 -1 作为 fd ).

Since you do not want any file backing, you can use the MAP_ANONYMOUS flag in the mmap call (also pass -1 as the fd).

这是手册页相关部分的摘录-

This is the excerpt for the related part of the man-page -

MAP_ANONYMOUS

MAP_ANONYMOUS

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

The mapping is not backed by any file; its contents are initialized to zero. The fd argument is ignored; however, some implementations require fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this. The offset argument should be zero. The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is supported on Linux only since kernel 2.4.

这篇关于自定义堆/内存分配范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆