3

本质上,我希望能够做这样的事情:

//assume myFunction is defined and takes one argument that is an int
char * functionName = "myFunction";
int arg = 5;

__asm{
    push a
    call functionName
}

基本上我想调用一个名称存储在字符串中的函数。这样做的正确语法是什么?

编辑:我们正在谈论 x86 程序集

4

3 回答 3

1

You can't, at least not directly.

call takes an address as a parameter. Even though you write "call functionName", the linker replaces functionname with the actual address of the function. You'd need to first map that string to its address. In general, C and C++ don't support any sort of runtime metadata about function name mappings that would allow for this. If the function is exported from a DLL, you can use GetProcAddress to find its address.

If the list of functions is static, you can create the mapping ahead of time yourself.

Something like:

std:map<string, PVOID> functionMappings;
functionMappings["MyFunction"] = MyFunction;


// Later


PVOID function = functionMappings["MyFunction"];

__asm
{
    push a;
    call [function]
}

Some notes:

I believe the standard says that a function pointer may be larger than a PVOID. This should work on Windows x86/x64 platforms.

You didn't say what calling convention you were using - this code presumes stdcall.

This is a very, very odd thing to want to accomplish - what problem are you trying to solve?

于 2010-02-18T18:25:05.177 回答
1

This is not possible, you are trying to do a call-by-name operation. Assembler only has a call-by-value where value is an address. You need to convert the name to an address and pass the address to the assembler which means you need some kind of cross-reference between names and addresses. The compiler can help you out here, in C and C++ you need to look up function pointers to see the required syntax for getting the address of a function which can then be passed to the assembler.

Pre-emptive: Yes, sometimes the compiler can embed symbols into the executable which could then be searched through, but that's a method that is full of problems. The format of the data can change between compiler versions, the information can be stripped out by the linker and so on.

于 2010-02-18T18:25:23.320 回答
0

I don't know of any way to do this easily. In some higher level languages you can use reflection to achieve this but neither C nor assembly has that functionality available. By the time the linker is done all function calls are resolved to addresses. Maybe if you had access to some debug infrastructure you could do a reverse lookup on the function name to get its address but that would not be a trivial thing to achieve from assembly.

Or you could use function pointers defined at compile time to store the addresses of the functions you are interested in (although you'd still need some way to translate your string to a function pointer, presumably via a string compare table lookup). If this is something you are interested in doing I'd suggest writing the C equivalent and then looking at the assembly code that the compiler outputs to see how it handles function pointers.

于 2010-02-18T18:30:14.367 回答