fastcall_caller
code:c++
/**
* @brief __fastcallのfuncを実行する。スタック除去のタイミングが問題にならないように実行できる
*
* @param arg_n funcの引数の数(最小3)
* @param func __fastcallの関数のポインタ
* @param arg0 1番目の引数
* @param arg1 2番目の引数
* @param arg2 3番目の引数
* @param ... 4番目以降の引数
* @return EAXでそのまま返す
*
* @note 引数が2個以下の場合はこの関数を経由する意味は無いため出来ないようにしました。func(arg0, arg1)で呼び出してください
* @warning 浮動小数や非32bitの引数は考慮していない
*/
inline __declspec(naked) intptr_t __cdecl fastcall_caller(int arg_n, void* func, intptr_t arg0, intptr_t arg1, intptr_t arg2, ...) {
__asm {
mov edx, ebp
add ecx, 0x03
SHIFT_STACK:
add ebp, 0x04
loop SHIFT_STACK
add esp, 0x08
ret
}
}
__fastcallを実行して呼び出し側スタック除去が出来るようなコードを目的に作っていったわけですが、最終的にはfuncが関数側スタック除去でも正常に動作するようなものになりました。
旧
新たにpushして実行しているのが無駄
code:c++
/**
* @brief __fastcallのfuncを実行する。スタック除去のタイミングが問題にならないように実行できる
*
* @param func __fastcallの関数のポインタ
* @param arg_n funcの引数の数(最小3)
* @param arg0 1番目の引数
* @param arg1 2番目の引数
* @param arg2 3番目の引数
* @param ... 4番目以降の引数
* @return EAXでそのまま返す
*
* @note 引数が2個以下の場合はこの関数を経由する意味は無いため出来ないようにしました。func(arg0, arg1)で呼び出してください
* @warning 浮動小数や非32bitの引数は考慮していない
*/
inline __declspec(naked) intptr_t __cdecl fastcall_caller(void* func, int arg_n, intptr_t arg0, intptr_t arg1, intptr_t arg2, ...) {
__asm {
push ebp
mov ebp, esp
sub ecx, 2
jg skip_arg_count_min
mov ecx, 1
skip_arg_count_min:
push_args_loop:
sub eax, 4
loop push_args_loop
call eax
mov esp, ebp
pop ebp
ret
}
}