• 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

  • 相关阅读:
    详解TCP三次握手
    Linux(Ubunt)使用日记------常用软件汇总(不定时更新)
    Linux(Ubuntu)使用日记------markdown文件与pdf,doc,docx文件的相互转化(pandoc使用)
    白板编程浅谈——Why, What, How
    深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
    我的算法学习之路
    redux的hook使用
    redux基础(添加中间件与异步)
    typescript书写规范
    用js手撕七种排序算法!!内附运行速度测试函数
  • 原文地址:https://www.cnblogs.com/findumars/p/5217973.html
Copyright © 2020-2023  润新知