Программирование - это просто
Advertisement
Главная arrow Уроки Delphi arrow Delphi изнутри arrow TObject (ClassNameIs, паскаль, ассемблер)
19.04.2024 г.
Главное меню
Главная
Интернет магазин
Программные продукты
Биржевые роботы
Искусственный интеллект
Математика и информатика
1С:Предприятие
Уроки C#
Уроки Delphi
Уроки программирования
Web-программирование
Дизайн и графика
Компьютер для блондинок
Исходники
Статьи
Платный раздел
Рассказы про компьютеры
Хитрости и секреты
Системный подход
Размышления
Наука для чайников
Друзья сайта
Excel-это не сложно
Все о финансах
.
TObject (ClassNameIs, паскаль, ассемблер) Печать E-mail
Автор megabax   
07.10.2009 г.
New Page 2

TObject (ClassNameIs, паскаль, ассемблер)

На прошлом уроке мы изучили метод ClassName класс TObject. Сегодня продолжим изучать класс TObject. Давайте посмотрим, как реализован метод ClassNameIs:

class function TObject.ClassNameIs(const Name: string): Boolean;
{$IFDEF PUREPASCAL}
var
  Temp: ShortString;
  I: Byte;
begin
  Result := False;
  Temp := ClassName;
  for I := 0 to Byte(Temp[0]) do
    if Temp[I] <> Name[I] then Exit;
  Result := True;
end;
{$ELSE}
asm
        PUSH    EBX
        XOR     EBX,EBX
        OR      EDX,EDX
        JE      @@exit
        MOV     EAX,[EAX].vmtClassName
        XOR     ECX,ECX
        MOV     CL,[EAX]
        CMP     ECX,[EDX-4]
        JNE     @@exit
        DEC     EDX
@@loop:
        MOV     BH,[EAX+ECX]
        XOR     BH,[EDX+ECX]
        AND     BH,0DFH
        JNE     @@exit
        DEC     ECX
        JNE     @@loop
        INC     EBX
@@exit:
        MOV     AL,BL
        POP     EBX
end;
{$ENDIF}

Как видим, данная функция просто напросто берет имя класса при помощи уже знакомой нам функции ClassName и побайтно сравниваем его с аргументом. Спрашивается, а почему бы просто не сравнить строки? Зачем нужен этот цикл:

for I := 0 to Byte(Temp[0]) do
    if Temp[I] <> Name[I] then Exit;

Этот вопрос задал себе и я. Сперва подумал, что дело в том, что при простом сравнении сравнивается каждый байт строки, а здесь только до момента первого несовпадения. Теоретически это должно работать быстрее. Но сразу возникает вопрос: а что если параметр Name окажется длиннее, но его начало полностью совпадет с именем класса? Иными словами, пусть у  нас класс назван "TMyClass", а мы производим сравнение с "TMyClass1" и у нас будет результат true, что явно ошибочно.

Для того, что бы разобраться, я поискал информацию в Интернете, позадавал вопросы на форумах и выяснил, что код на паскале ошибочный, видимо, из за того, что перекомпилировать исходные модули, нужно хорошо извратиться, а по умолчанию модули скомпилированы именно с отключенной директивой  PUREPASCAL, вот и не тестировали разработчики Delphi достаточно хорошо эту часть кода.

Теперь попробуем расшифровать ассемблерный код что бы убедиться, что он действительно работает правильно:

        PUSH    EBX
        XOR    EBX,EBX    // Result := False
        OR      EDX,EDX  // if Self==nil
        JE      @@exit    //    then Exit // этого на паскале нет
        MOV    EAX,[EAX].vmtClassName // tmp := Self.ClassName
        XOR    ECX,ECX        // L :=0
        MOV    CL,[EAX]      // L := tmp[0]
        CMP    ECX,[EDX-4]    // if L <> Length(Name)
        JNE    @@exit        //    then Exit // этого тоже нет
        DEC    EDX           
@@loop:                      // for i:= L downto 1 do
        MOV    BH,[EAX+ECX]  // if ((Temp[I]
        XOR    BH,[EDX+ECX]  //      xor Name[I])
        AND    BH,0DFH      //              and  $DF) // этого тоже нет
        JNE    @@exit        //                  <>0 then Exit;
        DEC    ECX
        JNE    @@loop       
        INC    EBX            // Result := true
@@exit:
        MOV    AL,BL
        POP    EBX
 

 

Последнее обновление ( 09.11.2011 г. )
 
« След.   Пред. »
 
© 2024 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги