[疑难] 请教内联汇编
hurd
2009-07-04
一个小程序需要调用delphi写的dll, 查到delphi写的函数先用EAX, EDX, ECX传递参数,大于3个参数才使用栈传递。
现在无法修改delphi写的dll, 需要调用它里面的函数带2个参数(使用EAX和EDX传递)。 直接写的asm没用naked调用一直失败。debug时候看到EDX值根本就没赋上。 EAX好象也是错误的。 现请教各位如何用asm naked写个调用delphi函数的程序。 下面的好象是错误的。。。。 extern(C) uint lib_test2(void* p1, void* p2, void* pDelphiFun){ asm{ naked; push EDI; push EBX; push ESI; mov EAX, [ESP + 2*4]; // p1 mov EDX, [ESP + 1*4]; // p2 mov ECX, [ESP + 0*4]; // pDelphiFun call dword ptr ECX; pop EBX; pop EDI; pop ESI; ret 4; } } |
|
RednaxelaFX
2009-07-05
用EAX、EDX、ECX传前三个参数这是Borland的fastcall calling convention;这也是Delphi的默认calling convention,称为register calling convention。
无法修改Delphi代码么……那就没办法加上export; stdcall;来改变calling convention了 = = 我现在没环境测试,不过印象中GDC和DMD对extern(C)生成的calling convention不完全一样?楼主是用哪个编译器来编译的?DMD的话应该用的是Win32的stdcall,那么就是全部参数都通过栈来传递。那样的话,在32位平台上如果用了naked编译器就不去动EBP的话,那函数开头的地方dword ptr [esp]所指向的应该是返回地址,[esp+4*1]是第一个参数,[esp+4*2]是第二个参数,[esp+4*3]是第三个参数。 你要调用的Delphi的“东西”是函数还是方法?换句话说有没有隐含的Self?调用的是方法的话,隐含的Self会作为第一个参数从EAX传递进去。 我不太肯定……楼主要不要试试这样行不行? extern(C) uint lib_test2(void* p1, void* p2, void* pDelphiFun) { asm{ naked; enter 0, 0; mov EAX, p1[EBP]; mov EDX, p2[EBP]; mov ECX, pDelphiFun[EBP]; call dword ptr ECX; leave; ret 4; } } 如果给出了错误的信息,很抱歉……我对D和Delphi的互操作也不熟,纯粹充个胖子而已 =v= 希望有帮助 |
|
hurd
2009-07-05
首先谢谢回答,还有如下问题请教:
ret 4; 是传递一个参数时候的情况吗? 我看tango里ret的数字都没规律,动态数组应该算2个参数。但是总数有不一样。。 |