雖然其實只是抄了一遍而已,不過之後我會考慮使用純彙編啓動一次看看
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