由一个vc内嵌asm的BUG引出的...

原创 2006年05月24日 01:39:00
在语法上, 我们通常认为以下的两条语句是等价的:
mov ecx, offset DATA_LABLE     //其中DATA_LABLE是数据定义标签
lea ecx, DATA_LABLE

而更进一步, 我们也会认为以下两句是等价的:
mov ecx, ebp-8
lea ecx, [ebp-8]

第一种, 用的是存储器寻址方式; 而第二种, 用的是寄存器寻址和寄存器间接寻址方式. 让我意想不到的是, 在第二种情况下, vc的处理并没有让寄存器寻址和寄存器间接寻址方式的mov和lea两者之间实现等价. 在使用 _asm{} 的方式将"mov ecx, ebp-8"这条语句括起来编译之后, 很遗憾地, 我在vc的反汇编窗口发现它变成了这样的一条语句: "mov ecx, ebp". 啊哦, 我的"-8"竟然不翼而飞了! 到目前为止, 我尚没有查到造成这种现象的原因所在, 我只能暂时将它归为vc的bug了.

对gcc下会不会存在这个问题呢? 为更进一步证实, 我使用gcc重新写了这句代码: "mov ecx, ebp-8", 但重写后的代码由当初的一句变成了这样的两句:
movl %ebp, %ecx
subl $8, %ecx

之所以改写成这样的两句, 是因为我发现在AT&T的汇编语法中, 对于双寄存器寻址的操作, 不能对寄存器取的值作任何变换, 也就是说不能写成"movl %ebp-8, %ecx"的形式, 而寄存器间接寻址的操作就可以作变换, 比如:
movl -8(%ebp), %ecx             此句相当于intel asm里的:   mov ecx, [ebp-8]
movl (%ebp, %eax), %ecx         此句相当于intel asm里的:   mov ecx, [ebp+eax]
movl (%ebp, %eax, 4), %ecx      此句相当于intel asm里的:   mov ecx, [ebp+eax*4]
movl -8(%ebp, %eax, 4), %ecx    此句相当于intel asm里的:   mov ecx, [ebp+eax*4-8]

从以上几条语句来看, 似乎AT&T语法对寄存器间接寻址方式的支持没有intel asm更具人性化, 但我猜想AT&T之所以采用这样的方法, 可能一定程度上也是为了提高微指令级的执行效率.

当然, "mov ecx, ebp-8"这句也可以改写成这样的两句:
subl $8, %ebp
movl %ebp, %ecx

但一般不会这么作, 道理是很显然的, ebp通常会作为函数内的基址寄存器, 用于存放函数入口点的堆栈首地址, 这个值的改变会直接影响其后语句对局部变量以及函数参数的引用发生变化, 所以, 在函数首部之后的执行体中, ebp通常是不允许被改变的, 这也是我们设计自己的汇编代码时所应该遵循的原则.

不知道vc为什么会将ebp之后的立即数作丢弃处理, 这显然是没有道德的行为. 这让我想起了这样的一句话: 不要试图帮助用户去纠正错误, 而是当错误发生时去提醒用户, 因为程序再聪明也不会始终明白设计者的真正意图 ,我们所需要作的就是"为异常捕获提供尽可能详细的日志, 并及时通知用户这种异常, 试图纠正异常的作法从方法上就是错误和愚蠢的".
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

MFC(VC,C++)下,OCX内使用另外一个OCX方法(内嵌OCX)-《零度屏幕录像软件》之笔记一

习惯性的美女镇博客 因为公司经常跨语言使用OCX, 如最常用的就是C#无法完成的东西(或者难以完成)(任何语言都有利弊), 需要C++的控件(ocx)完成, 但是OCX中又会牵涉到调用参数的问题,...

使用VC内嵌Python实现的一个代码检测工具

最近组内准备整顿代码,领导让我写个简单的python脚本分析代码中注释的行数和无效注释。因为这个需求不是很急,所以我想把简单的事情做复杂点。于是就写了一个用VC内嵌Python,并通过模拟按键和发消息...

Delphi内嵌ASM简易教程

前言   Delphi作为一个快速高效的开发平台,使用的人越来越多,但熟悉在Delphi代码中嵌入ASM代码的程序员我想不多,因为这方面的资料太少了,另一方面,它还需要有基本的汇编语言知识,关於...

C语言ASM汇编内嵌语法

我看到的原址:http://www.cnblogs.com/latifrons/archive/2009/09/17/1568198.html 这种资料貌似很难找。 .3 GCC Inline ASM...

n7:C内嵌ASM动态调用函数(stdcall)

#include #include #include #include #include #include #include #include #include using name...
  • alga_1
  • alga_1
  • 2012-03-17 19:18
  • 1621

将Mozilla源码里的内嵌Gecko示例winEmbed工程移植到VC

最近在学习怎么将Gecko嵌入到自己的应用程序中,下载了一份比较早一点的源码在对照官方文档痛苦地推进——网上相关资料确实相当缺乏,难道大家都各种webkit去了?我的计划是先弄清怎么用,让程序跑起来,...

(原创)一个JavaScript Function Outliner插件 第四版本 支持内嵌javascript,且可以对javascript进行压缩

这个版本离上个版本有些时日了,最近事情太多,这两天刚空闲下来就赶紧弄了下 要查看上个版本请点击这里 在今天发布的版本里对aspx/html页面嵌入的javascript也支持了,你可以折叠内嵌的j...

Build Your Own Angularjs 读书笔记(AngularJS牛逼的地方在于它内嵌了一个表达式到Function对象的编译器。。。当然还有DI框架)

Build Your Own Angularjs 读书笔记 目录  [隐藏]  1 项目配置2 作用域3 表达式与过滤器4 模块与依赖注入5 辅助函数6 指令 项目配置[编辑] npm ...
  • cteng
  • cteng
  • 2017-05-31 19:41
  • 925
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)