zoukankan      html  css  js  c++  java
  • Delphi中methodaddress的汇编代码解析

    class function TObject.MethodAddress(const Name: ShortString): Pointer;
    asm
            { ->    EAX     Pointer to class        }
            {       EDX     Pointer to name }
            PUSH    EBX
            PUSH    ESI
            PUSH    EDI
            XOR     ECX,ECX           //清零
            XOR     EDI,EDI           //清零
            MOV     BL,[EDX]          //获得字符串的长度
            JMP     @@haveVMT         //判断是否有虚拟方发表
    @@outer:                                { upper 16 bits of ECX are 0 !  }
            MOV     EAX,[EAX]
    @@haveVMT:
            MOV     ESI,[EAX].vmtMethodTable  //获得虚拟方发表的地址
            TEST    ESI,ESI                   //是否存在
            JE      @@parent                  //如果不存在
            MOV     DI,[ESI]                { EDI := method count           }方法的数量
            ADD     ESI,2                     // 开始  
    @@inner:                                { upper 16 bits of ECX are 0 !  }
            MOV     CL,[ESI+6]              { compare length of strings     }  //获得名城的长度
            CMP     CL,BL                                                      //比较长度 
            JE      @@cmpChar                                                  //如果相等就开始比较字符
    @@cont:                                 { upper 16 bits of ECX are 0 !  }
            MOV     CX,[ESI]                { fetch length of method desc   }  //获得方法的长度  //长度两个字节 指针4个字节  ///
            ADD     ESI,ECX                 { point ESI to next method      }  //指向下一个函数
            DEC     EDI
            JNZ     @@inner
    @@parent:                              //获得父的方发表
            MOV     EAX,[EAX].vmtParent     { fetch parent vmt              }
            TEST    EAX,EAX                //是否为0 
            JNE     @@outer                //不为零
            JMP     @@exit                  { return NIL                    }  //已经到根

    @@notEqual:
            MOV     BL,[EDX]                { restore BL to length of name  } //存储名字的长度
            JMP     @@cont                                                    //转移 

    @@cmpChar:                              { upper 16 bits of ECX are 0 !  }
            MOV     CH,0                    { upper 24 bits of ECX are 0 !  }  ///清空高位字节
    @@cmpCharLoop:
            MOV     BL,[ESI+ECX+6]          { case insensitive string cmp   }  //获得第一个字符
            XOR     BL,[EDX+ECX+0]          { last char is compared first   }  //比较
            AND     BL,$DF                                                     //清空其他标志位  
            JNE     @@notEqual
            DEC     ECX                      { ECX serves as counter         } //比较下一个
            JNZ     @@cmpCharLoop                                              //如果不为零 进行下一个字符的比较

            { found it }
            MOV     EAX,[ESI+2]              //找到 并且得到指针 12 方法长度 3456 方法指针 7890 方法名称 7 方法名城的长度

    @@exit:
            POP     EDI
            POP     ESI
            POP     EBX
    end;

    http://blog.csdn.net/diligentcatrich/article/details/8111297

  • 相关阅读:
    调试cuda程序一定要细心啊 不然一个bug会折腾你2天
    XML和实体类之间相互转换(序列化和反序列化)
    C#实现实体类和XML相互转换
    C#压缩打包文件例子
    通过锁字符串达到控制并发的效果C#
    巧用Ajax的beforeSend 提高用户体验
    HTML代码在线运行工具
    .NET使用ZXing.NET生成中间带图片和不带图片的二维码
    获取电脑硬件信息 (硬盘,cpu,内存等)
    C# http请求带请求头部分
  • 原文地址:https://www.cnblogs.com/findumars/p/5011861.html
Copyright © 2011-2022 走看看