【问题标题】:How can I get the beginning of the page of a memory address?如何获取内存地址页面的开头?
【发布时间】:2021-05-10 14:53:44
【问题描述】:

我正在尝试获取存储我的内存地址的页面的开头。我该怎么做? (Windows x64)

【问题讨论】:

  • 为什么需要这样做?您需要解决的实际问题是什么?是什么让您认为您实际上可以访问该内存而不会冒未定义行为的风险?
  • 好吧,你可以用 AND 关闭地址的低位来获得 4k 基地址,但你是否能用它做很多事情是另一回事 - 请参阅@Someprogrammerdude 评论:(
  • VirtualQuery 可能是你想要的

标签: c++ c windows memory virtual


【解决方案1】:

第一步是找出内存页的大小。在 C++ 中没有获取内存页大小的标准方法。查阅目标操作系统的文档。

在已知页面大小的情况下,我们需要将给定的指针与页面大小的边缘对齐。有一个标准函数std::align 几乎可以满足我们的要求,除了它向前对齐页面的末尾而不是回到开头。我们可以简单地向后调整一页:

inline void*
align_back(void* address, std::size_t alignment) noexcept
{
    void* aligned = address;
    std::size_t space = alignment;
    std::align(alignment, 1, aligned, space);
    return address == aligned
        ? aligned
        : static_cast<char*>(aligned) - alignment;
}

// example
void* beginning = align_back(address, page_size);

或者,我们可以稍微依赖实现相关的细节,并假设重新解释的整数的对齐方式与指针的对齐方式相匹配:

inline void*
align_back(void* ptr, std::size_t alignment) noexcept
{
    std::uintptr_t ptr_int = reinterpret_cast<std::uintptr_t>(ptr);
    std::size_t remainder = ptr_int % alignment;
    return static_cast<char*>(ptr) - remainder;
}

这往往会在我的测试中产生更好的组装。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多