內(nèi)聯(lián)匯編的技巧
有時(shí)我們的程序需要一些很高的執(zhí)行效率或者執(zhí)行系統(tǒng)底層的功能模塊,這些關(guān)鍵的部分我們可以采用內(nèi)聯(lián)匯編直接插入?yún)R編指令來(lái)達(dá)到我們的要求,以下是幾個(gè)技巧與大家共同探討.
1.內(nèi)聯(lián)匯編嵌入VC語(yǔ)句:
在VC中內(nèi)聯(lián)匯編非常方便,只需要按照如下格式
__asm{
//匯編語(yǔ)句
}
請(qǐng)看如下示例代碼
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
}
}
}
請(qǐng)注意示例代碼中兩個(gè)__asm塊中的pushad 和 popad 語(yǔ)句,pushad保存了寄存器環(huán)境,popad恢復(fù)了寄存器環(huán)境,使得m_pr.SetValue((float)s);語(yǔ)句對(duì)寄存器的影響被抵銷,你還可以調(diào)用其他任何語(yǔ)句。但建議是盡量少打斷內(nèi)聯(lián)匯編塊,以減少運(yùn)行時(shí)來(lái)回倒騰寄存器環(huán)境的時(shí)間。筆者的測(cè)試是,當(dāng)刪除m_pr.SetValue((float)s);并且合并兩個(gè)__asm塊,同時(shí)刪除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è)置斷點(diǎn)的方法來(lái)觀察FPU寄存器的情況,通常你用VC寫的代碼,不會(huì)被編譯為引用特殊指令集的代碼,雖然微軟號(hào)稱編譯器支持這些指令。所以你必須用內(nèi)聯(lián)匯編方法來(lái)調(diào)用這些指令以優(yōu)化程序,充分利用資源。示例中的代碼調(diào)用了FPU處理器的指令,使操作浮點(diǎn)數(shù)的能力被充分發(fā)揮。但當(dāng)然你還可以調(diào)用3DNOW!指令,SSE,SSE2等指令,但筆者沒有試過,如果你有什么新的發(fā)現(xiàn),還望賜教,再此先謝了!
總的來(lái)說內(nèi)聯(lián)匯編提高了速度,尤其是游戲編程,更應(yīng)該努力使用內(nèi)聯(lián)匯編,把CPU充分榨干,但壞處就是有些低端的機(jī)器無(wú)法運(yùn)行,兼容性差。同時(shí)微軟又號(hào)稱,編譯器不會(huì)去優(yōu)化你寫的匯編碼,他只是簡(jiǎn)單的翻譯為等價(jià)的機(jī)器碼,優(yōu)化的事情交給你自己來(lái)完成,所以你不但得是C++高手,同時(shí)還得是匯編高手。