注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

编程学习

我的网上家园

 
 
 

日志

 
 

VC++ 内联汇编的几点小经验  

2013-11-08 16:58:35|  分类: C学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
使用的是VC++6.0的版本,有以下几点小经验:

一:
VC++中局部变量,都是用ebp寄存器进行引用的,如果从其它程序中扣出来的汇编代码中使用了ebp寄存器,想要内联到自己的程序中,这真是一件很悲催的事情,但也有解决方法,虽然有些曲折.
函数的参数一般是用 ebp+4 ebp+8 引用的,而函数内定义的局部变量一般是用 ebp-4 ebp-8 引用的,如果内联一段汇编代码,并且这段代码使用了ebp寄存器,那么不仅仅是局部变量跟函数参数无法再用ebp引用,更严重的是如果处理不好,会导致栈不平衡,程序都不能运行.原因是什么呢?  请看以下代码:

push ebp
mov ebp,esp
sub esp,40h
push ebx
push esi
push edi
lea edi,[ebp-40h]
mov ecx,10h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]

... ...

pop edi
pop esi
pop ebx
add esp,50h
cmp ebp,esp
call __chkesp (004010d0)
mov esp,ebp
pop ebp
ret


这是VC++生成的函数体汇编代码的大体结构,可以看到程序是用ebp来保存esp的值的,函数返回前用ebp来比较esp的值是否一致,以保证在程序运行过程中可能出现失控时的异常处理.
解决方法是什么呢: 不使用ebp?但有时候做不到,因为有些代码是用ebp做偏移的,那么我们可以用esp来代替ebp对局部变量的引用,局部变量的定义也可以省略,采用直接汇编代码 sub esp,0x8 (根据需要减足够数量的字节) 来空出局部变量的内存空间,代码结束时使用 add esp,0x8来恢复栈平衡. 在开始内联之前先push ebp的值,在内联结束 pop ebp的值,这样就可以保证程序能正常运行了.
还有一种方案是,放弃局部变量,采用全局变量,全局变量因为有固定的偏移地址,所以不需要用ebp进行引用.

二: 内联时需要call 另外一段代码,但是发现程序出错了?
哦,别忘了汇编的程序执行顺序哦! 当用到call时,被call的代码如果在调用call的后面,那么它还是会被执行的,所以要用jmp跳过它.
  评论这张
 
阅读(135)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017