Asm+delphi

Тема в разделе "WASM.HEAP", создана пользователем frost, 13 янв 2006.

  1. frost

    frost New Member

    Публикаций:
    0
    Регистрация:
    13 янв 2006
    Сообщения:
    1
    Народ. подскажите, плз... Как вызвать метод какого-нить объекта из асмовской вставки...
     
  2. _staier

    _staier New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2003
    Сообщения:
    738
    Адрес:
    Ukraine
    изучаем sysutils.pas например

    или просто окно cpu открываем и смотрим как же на асме вызываются методы :derisive:
     
  3. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Подсказка: в любой метод неявным образом передается self, т.е. указатель на объект, который этот метод вызывает. В остальном - используется соглашение fastcall, насколько я помню.



    Однако проще всего не пытаться решить задачу умозрительно, а просто вызвать нужный метод в тестовой программе на Delphi и срисовать соответствующий код из встроенного отладчика.
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Срисовать один к одному для виртуальных методов не получится, т.к. кроме компилятора никто смещений методов в VMT не знает ;) Поэтому на асме можно вызывать методы объектов только статически без использования VMT и соответсвенно без всякого полиморфизма (т.е. действительный тип объекта должен быть известен заранее).

    В дельфях рулит соглашение о вызовах register: при вызове метода в eax передается указатель на объект, затем первые два параметра размеров до 4 байт в регистры edx и ecx, остальное через стек в порядке слева-направо (в противоположном stdcall). Примерчик:
    Код (Text):
    1. type
    2.   TFoo = class(..)
    3.     ...
    4.     function SomeFunc(x,y,z:integer);
    5.     ...
    6.   end;
    7. var
    8.   foo:TFoo; x,y,z:integer;
    9. begin
    10.   foo:=TFoo.Create;
    11.   ...
    12.   asm
    13.     mov eax,foo
    14.     mov edx,x
    15.     mov ecx,y
    16.     push z
    17.     call TFoo.SomeFunc
    18.   end;
    19.   ...
     
  5. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    leo

    т.к. кроме компилятора никто смещений методов в VMT не знает ;)

    не факт ;)

    еще помогает курить мануалы - ниже кусок делфевского хелпа.



    Two additional directives allow assembly code to access dynamic and virtual method: VMTOFFSET and DMTINDEX.

    VMTOFFSET retrives the offset in bytes of the virtual method pointer table entry of the virtual method argument from the beginning of the virtual method table (VMT). This directive needs a fully specified class name with a method name as a parameter, for example,TExample.VirtualMethod.



    DMTINDEX retrieves the dynamic method table index of the passed dynamic method. This directive also needs a fully specified class name with a method name as a parameter, for example,TExample.DynamicMethod. To invoke the dynamic method, call System.@CallDynaInst with the (E)SI register containing the value obtained from DMTINDEX.



    Note: Methods with the "message" directive, are implemented as dynamic methods and can also be called using the DMTINDEX technique. For example:


    Код (Text):
    1.     TMyClass = class
    2.       procedure x; message MYMESSAGE;
    3.     end;



    Код (Text):
    1. program Project2;
    2.  
    3. type
    4.   TExample = class
    5.     procedure DynamicMethod; dynamic;
    6.     procedure VirtualMethod; virtual;
    7.   end;
    8. procedure TExample.DynamicMethod;
    9. begin
    10. end;
    11. procedure TExample.VirtualMethod;
    12. begin
    13. end;
    14. procedure CallDynamicMethod(e: TExample);
    15. asm
    16.   // Save ESI register
    17.   PUSH    ESI
    18.   // Instance pointer needs to be in EAX
    19.   MOV     EAX, e
    20.   // DMT entry index needs to be in (E)SI
    21.   MOV     ESI, DMTINDEX TExample.DynamicMethod
    22.   // Now call the method
    23.   CALL    System.@CallDynaInst
    24.  
    25.   // Restore ESI register
    26.   POP ESI
    27. end;
    28. procedure CallVirtualMethod(e: TExample);
    29. asm
    30.   // Instance pointer needs to be in EAX
    31.   MOV     EAX, e
    32.   // Retrieve VMT table entry
    33.   MOV     EDX, [EAX]
    34.   // Now call the method at offset VMTOFFSET
    35.   CALL    DWORD PTR [EDX + VMTOFFSET TExample.VirtualMethod]
    36. end;
    37. var
    38.   e: TExample;
    39. begin
    40.   e := TExample.Create;
    41.   try
    42.     CallDynamicMethod(e);
    43.     CallVirtualMethod(e);
    44.   finally
    45.     e.Free;
    46.   end;
    47. end.
     
  6. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    вот еще до кучи...

    кусок кода неизвестного автора ;)


    Код (Text):
    1. // функция служит для получения указателя на байт, cледующий за адресом
    2. // последнего метода в VMT класса
    3. // возвращает nil в случае, если у класса нет VMT
    4. function GetVMTEnd(Cls: TClass): Pointer;
    5. asm
    6.         // Вход: Cls --> EAX
    7.         // Выход: Result --> EAX
    8.  
    9.         PUSH    EBX
    10.         MOV     ECX, 8
    11.         MOV     EBX, -1
    12.         MOV     EDX, vmtSelfPtr
    13. @@cycle:
    14.         ADD     EDX, 4
    15.         CMP     [EAX + EDX], EAX
    16.         JE      @@vmt_not_found
    17.         JB      @@continue
    18.         CMP     [EAX + EDX], EBX
    19.         JAE     @@continue
    20.         MOV     EBX, [EAX + EDX]
    21. @@continue:
    22.         DEC     ECX
    23.         JNZ     @@cycle
    24.         MOV     EAX, EBX
    25.         JMP     @@exit
    26. @@vmt_not_found:
    27.         XOR     EAX, EAX
    28. @@exit:
    29.         POP     EBX
    30.  
    31. end;
    32.  
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Max

    Спасибо за подсказку. Отстаю от жизни, однако :))



    Фичи конечно полезные, но вот интересно как их использовать в наследуемых классах со сложной иерархией. Берем к примеру стандартный TEdit и понятия не имеем какие у него методы виртуальные, какие динамические, а какие статические. Лазить по хэлпам и сорцам или действовать методом тыка ?
     
  8. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    Просто лазим по сорцам (vcl) или берем код на Delphi, компилируем и смотрим по ctrl+C какие методы виртуальные, а какие нет.