当前位置: 网学 > 编程文档 > 汇编语言 > 正文

VC7中汇编和C++混合的初步心得

来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/18
下载{$ArticleTitle}原创论文样式
ash;你会发现:任何包含了内嵌汇编的 inline 成员函数都不会被内联!


3 汇编/内联函数和效率

普通函数是可以内联的,下面就是一个完美的结合 C++/ asm 的例子:

inline long long getTimer(){
long long time;
__asm rdtsc
__asm mov DWORD PTR time, eax
__asm mov DWORD PTR time + 4, edx
return time;
}

rdtsc指令用来获得CPU自开机运行的时钟周期数。它的结果是64位的,保存到 eax 和 edx两个寄存器中,可以用来精确测量算法开销。上面的函数内联之后, 局部变量不见了, 临时返回值也不见了,只有最核心的三行代码,没有比这更简洁的了:

; 68 : long long b = getTimer();

rdtsc
mov DWORD PTR _time$11298[ebp], eax
mov DWORD PTR _time$11298[ebp+4], edx

成员函数内联则又是另一个故事:系统不知道如何处理this,所以他干脆忽略所有内嵌asm成员函数的内联标志。

好嘛,VC不愿上,我们用皮鞭赶着他上! 把第二部分最初那个 A::i 改为 __forceinline 就强制内联了——也就是强制VC犯错误了:不幸的编译器看不懂我们的代码,只好把指令抄到函数调用处。他不晓得初始化ecx,那个mov可能往任何地方写内容——比如把你的开机密码写到桌面上——

虽然可以手动设置ecx,不过我们可不希望看见如此丑陋的调用(想象一下你的同事看到这段代码的困惑):

__asm lea ecx, a
a.i( 20 );

要正确编写能成功内联的代码必须结合另一个方案,手动复制this:

__forceinline void A::i( int n ){
__asm mov ecx, this
__asm mov eax, n
__asm mov [ecx]A._i, eax
}

厄。。。猜猜看结果如何?

首先看看我们直接用C++写一个 set函数 (譬如 void A::i( int n ){ _i = n; } )内联后的结果:

; 56 : a.i( 5 );

mov DWORD PTR _a$[ebp+8], 5

最残酷的结果也只需一句mov。 更可能的结果是——他被优化得连影儿都看不见。
然后看看我们的三年怀胎含辛茹苦研究出来的混合汇编的内联:

; 56 : a.i( 5 );

lea eax, DWORD PTR _a$[ebp]
pop ecx
mov DWORD PTR $T11194[ebp], eax
mov ecx, DWORD PTR $T11194[ebp]
mov eax, 5
mov DWORD PTR [ecx+8], eax

这么长啊.生出一个怪胎 VC 中嵌入汇编的一个坏处是:编译器很难将他和C++协调,很难优化他。

汇编优化可以很快速、很强,但是一定要慎用。

  • 上一篇资讯: Linux下的汇编程序设计
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号