使用读取[EBP 4]的MSVC内联ASM移植到64位
Porting to 64-bit with MSVC inline asm that reads [ebp+4]
我在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 Inline ASM力量(,
[ebp+4]
保留返回地址。此代码只是设置void *pCaller = return_address
。
此代码只是保存分配内存的呼叫点的地址。(或至少将其与内存块的地址一起传递到doSomething
(。
这可能会阻止此operator new
插入呼叫者,因此删除这将是不错的。
如果您不需要此(例如,只是调试基础架构(,只需删除该部分,然后执行malloc
来实现operator new
。评论者建议现代调试工具可以为您做到这一点,使手动仪器过时。
或删除new
和delete
的过载,完全让他们使用默认的C new
/delete
。
或显然MSVC在返回地址中具有_ReturnAddress()
的 CC_12固有性,因此您可以在32位和64位代码中使用它,而不是Inline ASM,如果您真的想继续这样做。
请注意,在MSVC上,new
和delete
与malloc
/free
不兼容。它们是单独的分配器,带有单独的免费列表和/或簿记格式。
因此,如果其他代码仍然希望在这些指针上使用free()
,则即使不调用doSomething
,您也需要将其过载的new
/delete
保留。而且您需要继续使用malloc
,而不是使用其他方式调用默认的new
。
但是,如果唯一调用free
的是相应的删除操作员,则在源中只有一个位置可以更改/删除。
- 了解 C/C++ 中 Windows / MSVC 的一些反调试内联 asm
- 内联asm编译器屏障(内存阻塞器)是算作外部函数,还是算作静态函数调用
- 使用读取[EBP 4]的MSVC内联ASM移植到64位
- GCC内联ASM X86 CPU标志作为输入依赖性
- 内联 ASM:'out'的操作数类型不匹配
- C/C++内联asm操作数类型不正确
- 内联ASM将值写入内存
- 内联asm是ANSI C标准的一部分吗
- 无法在 VC++ 内联 ASM 中选择Microsoft位
- 将内联ASM转换为X64 igraph的固有
- 使用内联 ASM 获取字符串
- 内联 asm 分配给"FS:0":处理程序未注册为安全处理程序
- 内联asm:推送函数参数
- 64 位模式下 .asm 文件中的内联代码
- 将 64 位 int 作为输出传递到 32 位内联 asm
- 具有变量的 GCC 内联 ASM
- GCC 内联 ASM,未知的 SSE 操作码
- GCC 内联 ASM 跳转到带有交叉抛出异常的标签
- 内联 ASM 到 x64 - 理解
- GNU内联asm:哪些寄存器被__stdcall阻塞