有時我們的程序需要一些很高的執(zhí)行效率或者執(zhí)行系統(tǒng)底層的功能模塊,這些關(guān)鍵的部分我們可以采用內(nèi)聯(lián)匯編直接插入?yún)R編指令來達到我們的要求,以下是幾個技巧與大家共同探討.
1.內(nèi)聯(lián)匯編嵌入VC語句:
在VC中內(nèi)聯(lián)匯編非常方便,只需要按照如下格式
__asm{
//匯編語句
}
請看如下示例代碼
void CAlcmemDlg::OnButton3()
{
DWORD d=(m_size*1024*1024)/sizeof(DWORD);
DWORD*p=(DWORD*)m_p;
DWORD s;
m_pr.SetMin(0);
m_pr.SetMax((float)d);
m_pr.SetEnabled(TRUE);
if(NULL!=m_p){
__asm{
mov ecx,d
mov eax,0
L: mov edx,DWORD ptr p
mov [edx+eax],1 //隨便寫入數(shù)據(jù),此處寫入1
inc eax
mov s,eax
pushad
}
m_pr.SetValue((float)s);
__asm{
popad
loop L
}
}
}
請注意示例代碼中兩個__asm塊中的pushad 和 popad 語句,pushad保存了寄存器環(huán)境,popad恢復了寄存器環(huán)境,使得m_pr.SetValue((float)s);語句對寄存器的影響被抵銷,你還可以調(diào)用其他任何語句。但建議是盡量少打斷內(nèi)聯(lián)匯編塊,以減少運行時來回倒騰寄存器環(huán)境的時間。筆者的測試是,當刪除m_pr.SetValue((float)s);并且合并兩個__asm塊,同時刪除pushad,和popad后,速度明顯提高??梢娺@種打斷通常是得不償失。
通常要保存的寄存器環(huán)境還有Flags寄存器等,這些視具體情況而定。
2.自由使用FPU,MMX等指令[!--empirenews.page--]
void CAlcmemDlg::OnButton4()
{
float f_t=.132;
float f_s=0;
__asm{
fld f_s
fld f_s
fld f_s
fld f_t
fadd f_t
fst f_t
// fadd fs
}
}
可以利用設(shè)置斷點的方法來觀察FPU寄存器的情況,通常你用VC寫的代碼,不會被編譯為引用特殊指令集的代碼,雖然微軟號稱編譯器支持這些指令。所以你必須用內(nèi)聯(lián)匯編方法來調(diào)用這些指令以優(yōu)化程序,充分利用資源。示例中的代碼調(diào)用了FPU處理器的指令,使操作浮點數(shù)的能力被充分發(fā)揮。但當然你還可以調(diào)用3DNOW!指令,SSE,SSE2等指令,但筆者沒有試過,如果你有什么新的發(fā)現(xiàn),還望賜教,再此先謝了!
總的來說內(nèi)聯(lián)匯編提高了速度,尤其是游戲編程,更應該努力使用內(nèi)聯(lián)匯編,把CPU充分榨干,但壞處就是有些低端的機器無法運行,兼容性差。同時微軟又號稱,編譯器不會去優(yōu)化你寫的匯編碼,他只是簡單的翻譯為等價的機器碼,優(yōu)化的事情交給你自己來完成,所以你不但得是C++高手,同時還得是匯編高手。