关于内联汇编的几个技巧
作者:孙原
下载本文示例代码
有时我们的程序需要一些很高的执行效率或者执行系统底层的功能模块,这些关键的部分我们可以采用内联汇编直接插入汇编指令来达到我们的要求,以下是几个技巧与大家共同探讨.
1. 内联汇编嵌入VC语句:
在VC中内联汇编非常方便,只需要按照如下格式
__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 //随便写入数据,此处写入1 inc eax mov s,eax pushad } m_pr.SetValue((float)s); __asm{ popad loop L } } }请注意示例代码中两个__asm块中的pushad 和 popad 语句,pushad保存了寄存器环境,popad恢复了寄存器环境,使得m_pr.SetValue((float)s);语句对寄存器的影响被抵销,你还可以调用其他任何语句。但建议是尽量少打断内联汇编块,以减少运行时来回倒腾寄存器环境的时间。笔者的测试是,当删除m_pr.SetValue((float)s);并且合并两个__asm块,同时删除pushad,和popad后,速度明显提高。可见这种打断通常是得不偿失。
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 } }可以利用设置断点的方法来观察FPU寄存器的情况,通常你用VC写的代码,不会被编译为引用特殊指令集的代码,虽然微软号称编译器支持这些指令。所以你必须用内联汇编方法来调用这些指令以优化程序,充分利用资源。示例中的代码调用了FPU处理器的指令,使操作浮点数的能力被充分发挥。但当然你还可以调用3DNOW!指令,SSE,SSE2等指令,但笔者没有试过,如果你有什么新的发现,还望赐教,再此先谢了!