S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
调试程序调试到系统库函数的代码时,总会发现系统函数都是从一条MOVEDI, EDI指令开始的,紧接着这条指令下面才是标准的建立函数局部栈的代码。对系统DLL比如ntdll.dll进行反汇编,可以发现它的每个导出函数都是如此,并且每个导出函数开始处的MOVEDI, EDI上面紧接着5条NOP指令。比如在WinDbg中查看TextOutA周围的代码:
0:000> u TextOutA-0x0a L 10
GDI32!NtGdiTransparentBlt+0xa:
77efc43f ff12            call    dword ptr [edx]
77efc441 c22c00          ret     2Ch
77efc444 90              nop
77efc445 90              nop
77efc446 90              nop
77efc447 90              nop
77efc448 90              nop
GDI32!TextOutA:
77efc449 8bff            mov     edi,edi
77efc44b 55              push    ebp
77efc44c 8bec            mov     ebp,esp
很明显,两个字节的MOVEDI,EDI指令什么事情也不做,那么,就有两个问题:第一,为什么不直接从函数体开始而要从这条什么都不做的指令开始呢?第二,即使需要在函数一开始空出两个字节,为什么不直接使用两条NOP指令,而要使用这条MOV指令呢?在网上查阅一些资料后,得到了答案:
对于第一个问题,答案是为了实现hot-patching技术,即运行时修改一个函数的行为。修改过程如下:把MOVEDI, EDI修改为一条短跳转指令(一条短跳转指令恰好两个字节),把MOVEDI, EDI上面的五个NOP修改为一条长跳转指令(一条长跳转指令恰好五个字节),短跳转指令跳到长跳转指令上,长跳转指令跳到修改后的函数体上。
对于第二个问题,答案是为了提高效率。执行一条MOV指令比执行两条NOP指令花费更少的时间。
 
下面是在网上搜索到的相关资料:
http://blogs.msdn.com/ishai/archive/2004/06/24/165143.aspx
在这篇日志中作者指出这是一种实现hot-patching和hot-fix的技术,而且解释了为什么不使用detours技术来实现hot-patching。此外,作者提到了具体是如何使用这种技术来实现hot-patching的,但是只是一句话带过。
 
http://msmvps.com/blogs/kernelmustard/archive/2005/04/25/44413.aspx
这篇文章中作者从效率和其它方面详细解释了为什么选择用这种技术来实现hot-patching以及为什么要这样实现(短跳转加长跳转而不是一次性长跳转)。
 
http://xelf.info/knowledge/MemoryCopy.cpp
这里给出了具体的memcpy的C语言源代码。如果在安装VC6的时候选择了安装CRT源代码,则在VC安装目录的SRC/INTEL/目录中有memcmp.asm等文件,它们就是对应的CRT函数的源代码,这些源代码中也都有详细的注释。
 
另外,在自己的日志http://blog.csdn.net/jcwKyl/archive/2008/03/25/2217428.aspx里面,曾经对strcmp函数中的MOVEDI, EDI指令感到困惑,其实只要看看strcmp.asm中的源代码就可以明白,那条MOVEDI, EDI完全是为了内存四字节对齐的。源代码中写的是align 4,在运行时,如果需要一个填充字节,则会填充一条NOP指令,如果需要两个字节来填充,则会填充一条MOVEDI, EDI指令,之所以不用两条NOP,是出于效率的考虑。


标 题: XP系统程序中开头的MOV EDI,EDI指令的解释
发帖人:chaykovsky
时 间: 2005-11-25 13:55 
原文链接:http://bbs.pediy.com/showthread.php?threadid=18863

Feedback

# re: 函数开始处的MOV EDI, EDI的作用收藏  回复  更多评论   

2015-01-23 10:28 by abc
不错,谢谢分享。

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理