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

2016-02-19 16:19 3 1 收藏

人生本是一个不断学习的过程,在这个过程中,图老师就是你们的好帮手,下面分享的由一个vc内嵌asm的BUG引出的...懂设计的网友们快点来了解吧!

【 tulaoshi.com - 编程语言 】

  vc中内嵌asm时的bug

  在语法上, 我们通常认为以下的两条语句是等价的:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

mov ecx, offset DATA_LABLE     //其中DATA_LABLE是数据定义标签
lea ecx, DATA_LABLE

  而更进一步, 我们也会认为以下两句是等价的:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

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之后的立即数作丢弃处理, 这显然是没有道德的行为. 这让我想起了这样的一句话: 不要试图帮助用户去纠正错误, 而是当错误发生时去提醒用户, 因为程序再聪明也不会始终明白设计者的真正意图 ,我们所需要作的就是"为异常捕获提供尽可能详细的日志, 并及时通知用户这种异常, 试图纠正异常的作法从方法上就是错误和愚蠢的".

来源:https://www.tulaoshi.com/n/20160219/1611698.html

延伸阅读
随然这个问题可能很多人都没有遇到过,但遇到过的朋友相信和我一样,都经过了一断时间的问题查找才解决,为了减少这样的问题给你带来烦恼,在此我写下此文,希望对大家有所帮助。     你是否在创建JVM是老返回-1,即JNI_ERR;总么检查程序都没有发现任可问题,编译也不会出错。动态链接库文件“jvm.dll”已经放...
标签: Web开发
字体真是个麻烦的东西,然后又是个重要的东西。为以更方的解决字体问题,就像上次推荐的《》,为了Pixel Perfect,我们不断纠结。像支付宝在CSS Reset中是这样写的: body{ :12px Tahoma,Helvetica,Arial,,sans-serif}  而淘宝这样写: body, button, input, select, textarea { :12px/1.5 ta...
有些时候,我们需要我们的程序只运行一个实例,笔者自己作程序也有这样的情况,于是自已探究一番。忙活一阵后,总算小有收获,不敢独享,在天极发表出来,供大家参考。 既然是从根本上解决问题,对于Windows程序而言,就从WinMain函数入口,这是因为在VC中使用SDK的方式编写程序最透明,并且WinMain是作为VC编译器生成EXE文件的默认入...
一、新建一个基于对话框的程序 二、删除static 将确定改为颜色。 三、在dlg头文件里用class wizard添加以下消息映射 afx_msg void OnExitButton(); afx_msg void OnDestroy(); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnDrawButton(); 四、在头文件声明如下两个变量 int m_Radius; int m_direction; ...
标签: 电脑入门
问题:在word中如何画{ 一个大的根引出树状图? 解答:点击绘图工具栏上的自行图形基本形状,在基本形状里点击{ ,然后在文档中画出{。

经验教程

652

收藏

48
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部