繁体   English   中英

使用C ++,如何在msvc X64中获取堆栈指针的值

[英]Using c++, how do I get the value of the stack pointer in msvc X64

使用C ++,在X64上的msvc ++中,获取堆栈指针或对堆栈指针的最大值进行粗略估计的最快方法是什么?

我将使用它来编写此INLINE函数:

static __forceinline bool IsOnStack(const void *p) {
    return UINT_PTR(p) < __ESP;
}

如果更好的话,我可以将其用作宏

#define ISONSTACK(a)

谢谢!

编辑

我需要知道栈中是否有东西,以便其他代码不会释放它。 可以肯定地说,它是我正在更快地实现的智能指针的传统实现。 我需要处理的只是智能指针所指对象的地址。 我正在进行更改,以便智能指针可以引用堆栈上的项目,这将消除多余的堆分配。 64位堆栈似乎是一个相对较低的虚拟地址。 我们的分配器使用预定义的虚拟基地址(现在为16GB)。 我可以假设任何低于堆栈的内容。 该方法可能会意外地假设使用malloc或:: new分配的任何东西都在堆栈上,这不会是世界末日,因为我们不应该使用它们。 我想我会看看是否有更好的方法来了解堆栈在哪里。 只要我们没有误报,性能就比准确性更重要。

编辑

我知道我们目前仅将智能指针分配给已分配的内存,因为我们仅使用两种方式来设置智能指针:

new(spFoo) CFoo();  // uses an overridden new to do this

要么

spFoo = spOtherFoo;  

我正在考虑添加:

CFoo Foo();
spFoo = &Foo;

编辑我应该补充一点,我们不使用std库(部分是因为代码太旧了,部分是因为我们的应用程序处于极端情况并且性能如此重要)。 我不想就标准库进行辩论,我们都认为这很棒。 我没有此应用程序。 我们的代码仅在内部服务器上运行。 我们的代码都是64位。 有时我们使用线程,但这很少见。 可移植性不是问题。 我们使用的是Microsoft Visual Studio 2013,即vc ++2012。我们在服务器2008上运行。有一天我们将升级到服务器2012,而在Visual Studio 2015发布时将升级到服务器。

这始于通常没有关于内联汇编的抱怨。 然后,我很难找到有关在Windows上运行的vc ++应用程序的常规内存布局(堆栈在哪里,堆栈在哪里等)的文档。

好的,所以这将比“评论”值长。

首先,“知道是否需要释放”应该用std::shared_ptrstd::unique_ptr ,而不是通过“检查它是否在堆栈中”来解决。 关于什么:

void Function(int *p)
{
    if (!isOnStack(p)) delete p;
}


std::vector<int> v;

... fill stuff into v ... 
Function(&v[14]); 

std::vector中间释放几乎是一件非常糟糕的事情-但我保证地址不在堆栈中。

static int x;
Function(&x); 

那里没有更好的选择-它也会导致不良的释放。

至于“堆栈位于何处”则完全基于运行时环境(OS和编译器的组合等)。 它可能是一个高位地址。 它可能在“主”线程中是一个高地址,而在辅助线程中可能是一个低地址-但您并不是真的希望它仅在“主”线程中起作用,对吗?

当然,线程堆栈的位置还完全取决于提供线程(以及堆栈分配)的OS和运行时库。

您可能可以执行以下操作:

uintptr_t sp_base;

bool isInStack(void *p)
{
    int x;
    uintptr_t sp_top = (uintptr_t)(&x);
    // Assumes stack grows towards 0.
    return (p > sp_top) && (p < sp_base);
}

int main()
{
    int x;
    sp_base = (uintptr_t)(&x); 
    ... 
}

但是,它并不能保证每次甚至在大多数时间都能正常工作-根据实际的操作系统和编译器选择,结果可能会有很大的不同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM