当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 关于内联汇编的几个技巧

VC++
透明窗体的又一实现
橡皮区矩形 CRectTracker C# 实现
Visual Basic .NET 中多 Windows 窗体的同步
轻松实现类 MSDN 2002 界面(二)
轻松实现类 MSDN 2002 界面
数据库开发之窗体编程
一个打印报表的简单的类
SDK 程序使用SkinMagic工具包换皮肤
Windows SDK笔记(七):创建MDI窗口
Windows SDK笔记(六):使用对话框资源建立窗口
Windows SDK笔记(五):非模式对话框
Windows SDK笔记(四):模式对话框
也谈如何隐藏显示在任务栏中的对话框程序
一个托盘程序演示 -闹钟 Alert
think window procedure
再谈 CFileDialog 对话框的定制
获得 Win32 窗口句柄的更好的方法
个人考勤软件开发实例配套代码 2.1版(Update)
介绍一个操作DHTML表格的C++对象
Windows资源管理器Web视图界面

VC++ 中的 关于内联汇编的几个技巧


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 45 ::
收藏到网摘: n/a

关于内联汇编的几个技巧
作者:孙原

下载本文示例代码

有时我们的程序需要一些很高的执行效率或者执行系统底层的功能模块,这些关键的部分我们可以采用内联汇编直接插入汇编指令来达到我们的要求,以下是几个技巧与大家共同探讨.

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,0L:	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后,速度明显提高。可见这种打断通常是得不偿失。
通常要保存的寄存器环境还有Flags寄存器等,这些视具体情况而定。

2. 自由使用FPU,MMX等指令
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等指令,但笔者没有试过,如果你有什么新的发现,还望赐教,再此先谢了!
总的来说内联汇编提高了速度,尤其是游戏编程,更应该努力使用内联汇编,把CPU充分榨干,但坏处就是有些低端的机器无法运行,兼容性差。同时微软又号称,编译器不会去优化你写的汇编码,他只是简单的翻译为等价的机器码,优化的事情交给你自己来完成,所以你不但得是C++高手,同时还得是汇编高手。不过据我所知这种人十有八九是黑客。我是不鼓励你成为那类人的,撰写此文只为抛砖引玉。

作者信息:
姓名:孙原(2002-8-16于西安)
E-mail:[email protected]
QQ:41750362