虽然其实只是抄了一遍而已,不过之后我会考虑使用纯汇编启动一次看看
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_WINDOWED, true);
if(hge->System_Initiate())
{
hge->System_Start();
hge->System_Shutdown();
}
hge->Release();
首先是C++的代码。以上代码就足以运行一个简单的hge了,当然库和头文件自己导进去,全局的hge指针也需要声明下。
__asm
{
push 180h
call hgeCreate
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+24h]
push offset FrameFunc
push 8
push eax
mov dword ptr [hge],eax
call edx
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+20h]
push 1
push 1
push eax
call edx
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+4]
push eax
call edx
test al,al
je ENDMARK
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+0Ch]
push eax
call edx
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+8]
push eax
call edx
ENDMARK:
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx]
push eax
call edx
}
用内联汇编的话就是这个感觉。可以看到虚函数其实就是每次偏移然后call,hge指针包含了虚函数表的起始地址,每次根据偏移调用不同的函数,然后还要传入this指针,这一步跟C如出一辙,但是简化了调用过程。hge是stdcall,所以堆栈也不用自己手动恢复了。
ecx,dword ptr [eax]
其实我并不理解这句的用意。看起来是将hge的地址给eax,而又将eax的地址给力ecx,其实是完全没有理解dword ptr的含义,继续慢慢看书吧
果然内联什么的还是有点太弱了的感觉,直接使用win32汇编吧,原本编译出来7k的程序,一下子变成了2.5k
.386
.model flat,stdcall
option casemap:none
hgeCreate proto :DWORD
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
includelib hge.lib
includelib hgehelp.lib
.data
hge DWORD ?
.code
start:
push 180h
call hgeCreate
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+24h]
push offset FrameFunc
push 8
push eax
mov dword ptr [hge],eax
call edx
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+20h]
push 1
push 1
push eax
call edx
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+4]
push eax
call edx
test al,al
je ENDMARK
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+0Ch]
push eax
call edx
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx+8]
push eax
call edx
ENDMARK:
mov eax,dword ptr [hge]
mov ecx,dword ptr [eax]
mov edx,dword ptr [ecx]
push eax
call edx
invoke ExitProcess,0
FrameFunc proc
xor al,al
ret
FrameFunc endp
end start