[疑难] 请教内联汇编

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个参数。但是总数有不一样。。
Global site tag (gtag.js) - Google Analytics