我最近问了一个问题:一个看似用 MSVC 编译的 IA-32 程序如何通过 EAX 发送它的唯一参数?发布问题后,我发现另一个函数传入了第一个参数EAX,然后推送了其剩余的参数。然后调用者清理堆栈。
调用代码:
.text:00402465 lea eax, [ebp+var_4]
...
.text:00402469 push eax
.text:0040246A mov eax, [ebp+hWnd]
.text:0040246D call openFileDialog
.text:00402472 add esp, 4
和函数本身:
.text:00411730 openFileDialog proc near
.text:00411730
...
.text:00411730 arg_0 = dword ptr 8
.text:00411730
.text:00411730 push ebp
.text:00411731 mov ebp, esp
.text:00411733 sub esp, 18h
.text:00411736 cmp byte_42AE1D, FALSE
.text:0041173D push ebx
.text:0041173E push esi
.text:0041173F push edi
.text:00411740 mov esi, eax
...
.text:00411789 mov eax, [ebp+arg_0]
.text:0041178C push eax
.text:0041178D push esi
.text:0041178E call openFileDialog_Compat
.text:00411793 add esp, 8
如您所见,在函数中, 的值EAX在任何影响它之前保存,因此它肯定被用作参数。稍后,推送的参数被传递给一个普通的 __cdecl 函数。
该程序链接到使用 msvcr100.dll 并始终使用 MSVC 样式(例如 __security_cookie、MSVC 名称修改等),因此它似乎是使用 Visual C++ 编译的,但这种不寻常的调用约定让我对此表示怀疑。