gpt4 book ai didi

c++ - 使用读取 [ebp+4] 的 MSVC 内联 asm 移植到 64 位

转载 作者:行者123 更新时间:2023-11-30 01:33:53 25 4
gpt4 key购买 nike

我在 Microsoft Visual Studio 2010 中工作,我正在尝试为我的项目支持 64 位构建。据我所知,64 位架构不支持 __asm 关键字。

下面是当项目只支持 32 位构建时它是如何工作的。

void* 
Class1::Class2::operator new(size_t size)
{
void *pCaller;
__asm mov edx, [ebp+4]
__asm mov pCaller, edx
char *pMem = (char *) malloc (sizeof(Class2) + size);
doSomething(pMem, pCaller);
void *ptr = (void *) (pMem + sizeof(Class2));
return(ptr);
}

我可以使用预处理器指令使上述功能取决于建筑类型。

void* 
Class1::Class2::operator new(size_t size)
{
#ifndef _WIN64
void *pCaller;
__asm mov edx, [ebp+4]
__asm mov pCaller, edx
char *pMem = (char *) malloc (sizeof(Class2) + size);
doSomething(pMem, pCaller);
void *ptr = (void *) (pMem + sizeof(Class2));
return(ptr);
#elseif
// Accptable code for 64-bit project.
}

我必须以某种方式摆脱那些线条

__asm mov edx, [ebp+4] 
__asm mov pCaller, edx

我以前从未遇到过汇编代码,但据我所知

__asm mov edx, [ebp+4]

在寄存器之间移动数据,[ebp+4] 是函数调用 Class1::Class2::operator new(size_t size) 中定义的局部变量,存储在堆栈中。第二行只是在寄存器和内存之间移动数据。

如何用 C/C++ 替换汇编代码?这可能吗?

最佳答案

假设 EBP 设置为遗留帧指针(我认为 MSVC 内联 asm 强制),
[ebp+4] 保存返回地址。这段代码只是设置void *pCaller = return_address

此代码只是保存分配内存的调用站点的地址。 (或者至少将它与内存块的地址一起传递给 doSomething)。

这可能会阻止这个 operator new 内联到调用者中,所以删除它会很好。


如果您不需要这个(例如,它只是调试基础设施),只需删除该部分并执行malloc 来实现operator new。评论者建议现代调试工具可以为您完成这项工作,从而使手动检测变得过时。

或者完全移除newdelete的重载,让它们使用默认的C++ new/删除

或者显然 MSVC 有一个 _ReturnAddress() intrinsic in intrin.h对于返回地址,因此如果您真的想继续这样做,您可以将它用于 32 位和 64 位代码而不是内联 asm。


请注意,在 MSVC 上,newdeletemalloc/free 不兼容. 它们是独立的分配器,具有独立的空闲列表和/或簿记格式。

所以如果其他代码仍然想在这些指针上使用free(),您确实需要保留重载的new/delete这个类,即使它不调用 doSomething。并且您需要继续使用 malloc,而不是使用其他方式调用默认的 new

但如果唯一调用 free 的是相应的删除运算符,那么您的源代码中只有一个地方可以更改/删除。

关于c++ - 使用读取 [ebp+4] 的 MSVC 内联 asm 移植到 64 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57316399/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com