XYZ*_*123 1 c++ porting x86-64 inline-assembly visual-c++
我正在使用 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);
}
Run Code Online (Sandbox Code Playgroud)
我可以使用预处理器指令使上述函数取决于建筑类型。
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.
}
Run Code Online (Sandbox Code Playgroud)
我必须以某种方式摆脱这些线条
__asm mov edx, [ebp+4]
__asm mov pCaller, edx
Run Code Online (Sandbox Code Playgroud)
我以前从未遇到过汇编代码,但据我所知
__asm mov edx, [ebp+4]
Run Code Online (Sandbox Code Playgroud)
在寄存器之间移动数据,[ebp+4]是Class1::Class2::operator new(size_t size)
存储在堆栈上的函数调用内部定义的一些局部变量。第二行只是在寄存器和内存之间移动数据。
如何用 C/C++ 替换汇编代码?这可能吗?
假设 EBP 设置为遗留帧指针(我认为这是 MSVC 内联汇编强制的),
[ebp+4]
保存返回地址。 这段代码只是设置void *pCaller = return_address
。
这段代码只是保存分配内存的调用站点的地址。(或者至少将其doSomething
与内存块的地址一起传递给 )。
这可能会阻止它operator new
内联到调用者中,所以删除它会很好。
如果您不需要这个(例如,它只是调试基础设施),只需删除该部分并执行即可malloc
实现operator new
。评论者建议现代调试工具可以为您做到这一点,从而使手动检测变得过时。
或者完全删除new
和的重载,delete
让它们使用默认的 C++ new
/ delete
。
或者显然 MSVC 有一个_ReturnAddress()
内在的intrin.h
返回地址,因此如果您确实想继续这样做,您可以将其用于 32 位和 64 位代码,而不是内联汇编。
请注意,在 MSVC 上,new
和与/delete
不兼容。malloc
free
它们是具有单独空闲列表和/或簿记格式的单独分配器。
因此,如果其他代码仍然想在这些指针上使用free()
,您确实需要保留此类的重载new
/ ,即使它不调用. 并且您需要继续使用而不是使用其他调用默认值的方式。delete
doSomething
malloc
new
但是,如果唯一调用的free
是相应的删除运算符,则源中只有一个位置可以更改/删除。