索引ARGS为Windows数组X86-64 ABI [英] Indexing args as an array in the Windows x86-64 ABI

查看:110
本文介绍了索引ARGS为Windows数组X86-64 ABI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图端口一个包装函数从32位到X86-64 ASM为Windows ABI。功能取决于索引到它的参数作为一个数组。

我知道MSVC不能在X64项目做内联汇编,但我有兴趣建立同等功能到X64 .ASM文件。

该函数将通过StackFrame为被称为API。

  __ declspec(裸体)PVOID WINAPIV CGX86(FARPROC lpPtr,UINT lpSize,...)
{
    __asm​​ {
        推EBP;
        MOV EBP,ESP;
        LEA EAX,[EBP + 0×04];
        MOV [EBP - 0×04],EAX;
        MOV EAX,[EBP - 0×04]。
        MOV ECX,[EBP +的0x0C];
        加ECX,2;
ParseArgs:
        CMP ECX,2;
        JZ短MoveFinal;
        推DWORD PTR [EAX + ECX * 0×04]。
        子ECX,1;
        JMP短ParseArgs;
MoveFinal:
        调用[EBP + 0×08];
        MOV ESP,EBP;
        流行EBP;
        RETN;
    }
}

例如使用:

  CGX86((FARPROC)MessageBoxA,4,GetForegroundWindow(),身体,TITLE,MB_OK);


解决方案

小丑的建议,它写在C是一个很不错的,尤其。如果可以联到电话里的一些参数的个数是编译时常数。你的榜样用例传球大多是编译时间常数ARGS,包括函数指针。 任何像样的优化编译器将内联这一点,并优化掉的间接逼到用正确的ARGS一个正常的函数调用。确保将定义某个地方,这可以被内联。


不过,如果你不能让编译器作出漂亮的code:

索引参数作为数组是功能的唯一的一块那非显而易见如何在64位的ABI实现,其中一些ARGS在暂存器。

在Windows 64位调用约定用于存储正下方的堆栈ARGS(阴影空间)4寄存器ARGS提供了空间,让你真正的可以的创造最多ARGS你可以索引只数组4条指令(存储ARGS到这些插槽)。你不需要特殊情况下,第一4 ARGS

不要忘了把传出ARGS到暂存器,而不是堆的,也和留下阴影空间,让您调用该函数。

由于罗斯岭指出,一定要包含指令创建SEH放松身心的独立汇编的信息。这是另一个很好的理由赞成一个纯C ++的解决方案,尤其。如果args来数量限制为一个小数目。

查看 86 标签维基调用约定等。

<一个href=\"http://stackoverflow.com/questions/4429398/why-does-windows64-use-a-different-calling-convention-from-all-other-oses-on-x86#comment58925184_35621290\">I'm不是在Windows调用约定一般,但它确实使实施无功ARGS功能进行简单的风扇。我是pretty肯定,这就是为什么影子空间在ABI存在。

I'm trying to port a wrapper function from 32bit to x86-64 asm for the Windows ABI. The function depends on indexing into its arguments as an array.

I know that MSVC cannot do inline assembly in X64 projects, but i am interested to build the equivalent function into a X64 .asm file.

The function sets the stackframe for the api to be called.

__declspec( naked ) PVOID WINAPIV CGX86( FARPROC lpPtr, UINT lpSize, ... )
{
    __asm {
        push ebp;
        mov ebp, esp;
        lea eax, [ ebp + 0x04 ];
        mov [ ebp - 0x04 ], eax;
        mov eax, [ ebp - 0x04 ];
        mov ecx, [ ebp + 0x0C ];
        add ecx, 2;
ParseArgs:
        cmp ecx, 2;
        jz short MoveFinal;
        push dword ptr [ eax + ecx * 0x04 ];
        sub ecx, 1;
        jmp short ParseArgs;
MoveFinal:
        call [ ebp + 0x08 ];
        mov esp, ebp;
        pop ebp;
        retn;
    }
}

example use:

CGX86( ( FARPROC )MessageBoxA, 4, GetForegroundWindow( ), "BODY", "TITLE", MB_OK );

解决方案

Jester's suggestion to write it in C is probably a good one, esp. if it can be inlined into calls where some of the args are compile-time constants. Your example use-case passes mostly compile-time-constant args, including the function pointer. Any decent optimizing compiler will inline this and optimize away the indirection into just a normal function call with the right args. Make sure you put the definition somewhere it can be inlined.


However, if you can't get the compiler to make nice code:

Indexing arguments as an array is the only piece of functionality that's non-obvious how to implement in the 64bit ABI where some args are in regs.

The Windows 64bit calling convention provides space for storing the 4 register args right below the stack args (the shadow space), so you actually can create an array of args you can index with only at most 4 instructions (store the args into those slots). You don't need to special-case the first 4 args.

Don't forget to put the outgoing args into regs instead of the stack, too, and leave shadow-space for the function you call.

As Ross Ridge points out, make sure you include directives to create SEH unwind info in the stand-alone asm. This is another good reason to favour a pure C++ solution, esp. if the number of args is limited to a small number.

See the tag wiki for links to calling conventions and so on.

I'm not a fan of the Windows calling convention in general, but it does make implementing var-args functions simple. I'm pretty sure that's why the "shadow space" exists in the ABI.

这篇关于索引ARGS为Windows数组X86-64 ABI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆