将32位ASM转换为64位

时间:2014-07-21 10:02:19

标签: assembly 64-bit inline-assembly masm intrinsics

我知道x64不支持内联汇编。我不太熟悉汇编,所以我想请任何精通它的人帮助我。任何人都可以将此代码从32位转换为64位吗?我已经读过你可以使用MASM或编译器内在函数,但有点混淆如何转换这段代码。

#define get_member_function_address_vc8(member_function_address, member_function_type)\
void* member_function_address;          \
{                                       \
    __asm                               \
{                                       \
    mov eax,offset member_function_type \
};                                      \
__asm                                   \
{                                       \
    mov member_function_address, eax    \
};                                      \
}

问候,马克

1 个答案:

答案 0 :(得分:0)

Ugg ......这是一些丑陋,丑陋的代码。正如David Wohlferd在评论中所说,Visual C ++在针对64位处理器时不支持内联汇编,因此您需要做一些不同的事情。

首先,我将尝试解释此宏正在尝试完成的内容。所有汇编指令正在执行的操作是将从第二个宏参数获取的32位值分配给使用作为第一个参数传入的名称声明的变量。它在做什么似乎相当于这个宏:

#define get_member_function_address(varname, member_function) \
     void *varname = (void *)&(member_function);

该宏被称为get_member_function_address的事实让我们知道为什么宏的作者认为有必要使用内联汇编来获取对象的地址。它试图获取成员函数的地址,但这并不容易。在成员函数上使用一元&运算符确实为您提供了一个指向成员函数的指针,但是指向成员函数的指针在C ++中是特殊的。它们不仅仅代表成员函数的地址,因此您无法将它们转换为void *

不幸的是,在C ++中没有可移植的方法来查找成员函数的地址。宏假定指向成员函数对象的指针具有位于对象开头的函数的地址。但是编译器可以将它放在任何想要的位置。显然这个假设对于32位版本的Visual Studio 2005(VS8)是正确的,但我不知道它是否也适用于任何其他版本。

假设它没有改变,那么以下代码应该是宏的替代品。它应该在针对32位和64位环境时起作用。也就是说,假设指向成员函数的指针在开始时具有成员函数的地址。

template <class T>
static inline void *
_get_member_function_address(T member_function_ptr) {
    union {
        T mf;
        void *p;
    } u;
    u.mf = member_function_ptr;
    return u.p;
}

#define get_member_function_address_vs8(varname, member_function)   \
    void *varname = _get_member_function_address(&member_function);