放假归来(25天时间,好长啊),继续向各位高手们学习,今天学习mfc内联汇编

关于内联汇编的几个技巧

作者:孙原


下载本文示例代码


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


 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后,速度明显提高。可见这种打断通常是得不偿失。

通常要保存的寄存器环境还有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:rock.sun@163.net

QQ:41750362


---------------------------------------------------------------


子程序的概念在VC中其实就是函数的意思,下面介绍的是在VC中调用汇编写的函数(汇编代码在.ASM VC代码在.CPP,


use ASM and CPP together:

1. create an ASM file

;;;;;;;;;;;;; asmsrc.asm:

.386

.model flat, stdcall

option casemap :none

.code


myasmproc proc dw1:DWORD,dw2:DWORD

mov eax,dw1

add eax,dw2

ret

myasmproc endp

end

;;;;;;;;;;;;end of asmsrc.asm


2. create a VC project name: useasm, type console application, A "Hello World" application


3. move the asm file to your project directory, then in VC project menu->Add to Project...->Files...

Files of type change to "all files", then you can select the asmsrc.asm, and click OK


4.in workspace window, FileView tab, select asmsrc.asm, right click to select "settings..." menu, custom build tab, put the following in commands edit box :

d:\masm32\bin\ml.exe /nologo /coff /Zf /c /Sa $(InputName).asm

put the following in Outputs edit box:

$(InputName).obj


5.edit your useasm.cpp as the following:

//useasm.cpp///

#include "stdafx.h"

#include <windows.h>

extern "C" int __stdcall  myasmproc(DWORD d1,DWORD d2);

int main(int argc, char* argv[])

{

printf("test of using cpp and asm together, if it works, it is done by masterz,otherwise I don't know who write this^_^\n");

int ret=myasmproc(22,33);

printf("ASM result:%d\n",ret);

return 0;

}


//end of useasm.cpp///


6. build the project and run it, it works.


notes: I assume you have installed masm32V8(you can get it from http://www.movsd.com/masmdl.htm)  at D:\masm32



相关文章
http://community.csdn.net/expert/topicview1.asp?id=1800052
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值