Смещения

Тема в разделе "WASM.BEGINNERS", создана пользователем sergegers, 27 сен 2011.

  1. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    Код (Text):
    1. lea edi, [ebp + x]
    2. lea eax, [edi + 3]
    3.  
    4. and eax, 0FFFFFFFCh
    5. mov esi, ds:InitializeCriticalSection
    6. push eax
    7. call esi
    как соотносится структура x и RTL_CRITICAL_SECTION ?
     
  2. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Структуры x нет, есть только RTL_CRITICAL_SECTION.
    Просто перед вызовом идёт выравнивание edi на четырёхбайтовую границу.
     
  3. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    в таком коде

    Код (Text):
    1. model flat, stdcall
    2.  
    3. struc X
    4. fied_0       dd
    5. z           dd
    6. field_8 dd 10 dup(?)
    7. X ends
    8.  
    9. fun proto: x:X
    10.     lea edi, [x + X.z]
    11.     lea eax, [edi + 3]
    12.     and eax, 0FFFFFFFCh
    13.     mov esi, ds:InitializeCriticalSection
    14.     push eax
    15.     call esi
    16. fun endp
    структура X выглядит так?

    Код (Text):
    1. struc X
    2. fied_0       dd
    3. z            RTL_CRITICAL_SECTION
    4. ...
    5. X ends
     
  4. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Код написан на Си и "структура" там выглядит так:
    struct X {
    RTL_CRITICAL_SECTION CriticalSection;
    ...
    };
     
  5. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    критическая секция является частью большей структуры. вопрос - начало RTL_CRITICAL_SECTION расположено по смещению 4 или 0?

    и ради интереса, такое обращение к критической секции это какой-то антиотладочный приём или особенности кодогенерации?
     
  6. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Нет. Начало RTL_CRITICAL_SECTION расположено по смещению x, где 0 <= x <= 3 -- число байт, нехватающих до выравнивания адреса до кратного четырём.

    Если структура X расположена по адресу xxx0, xxx4, xxx8 или xxxC, то x = 0. Если по xxx1, xxx5, xxx7, xxxD, то x = 3 и т.д.
     
  7. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Особенности кодогенерации. Правда мне не понятно почему компилятор вставил такой стаб - по умолчанию в Си все локальные переменные и члены структур выравниваются на четырёхбайтовую границу (в 32-хбитных системах).
    Если вы хотите написать аналог на ассемблере, выглядеть будет так:
    Код (Text):
    1. lea edi, [ebp + x]
    2. push edi
    3. call InitializeCriticalSection
    Но нужно тогда убедиться что edi делится без остатка на 4, если делиться не будет, то фунцкии для работы CRITICAL_SECTION будут работать некорректно.
     
  8. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    Код (Text):
    1. struct A
    2. {
    3.    BYTE z[0x17];
    4.    X x;
    5. };
    структура A создаётся оператором new, X - вышеобсуждаемая структура, значит ли это, что смещение равно 1?

    Ezrah большое спасибо
     
  9. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Видимо так оно и есть. Но я был уверен, что X уже будет выравнена путём добавления "пустых" байтов перед X x. Видимо, компилятор думает по-другому.
    Рад помочь.
     
  10. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    ну видимо было так:

    Код (Text):
    1. #pragma pack (push, 1)
    2. struct A
    3. {
    4.    BYTE z[0x17];
    5.    X x;
    6. };
    7. #pragma pack (pop)
     
  11. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Сомневаюсь. Однако, не могу опровергнуть. Можно, в принципе, поэкспериментировать и посмотреть, что получается на выходе.
    Кстати, если
    , то как переменные оказываются на стеке?
     
  12. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    это же указатель на структуру, а не структура

    Код (Text):
    1. struct A
    2. {
    3.    BYTE z[0x17];
    4.    X x;
    5. };
    6.  
    7. void stdcall foo(A *a)
    8. {
    9.   InitializeCriticalSection(&a->x.CritSec);
    10. };
    11.  
    12. void main()
    13. {
    14.   A *a = new A();
    15.   foo(a);
    16. }
     
  13. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Можно листинг всей функции?
     
  14. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    Код (Text):
    1. .text:007940C8 228                 push    size A    ; nBytes = 0xE44
    2. .text:007940CD 22C                 call    new
    3. .text:007940D2 22C                 add     esp, 4
    4. .text:007940D5 228                 cmp     eax, zero
    5. .text:007940D7 228                 jz      short allocation_failed_2
    6. .text:007940D9 228                 push    eax             ; this
    7. .text:007940DA 22C                 call    A_ctor
    8.  
    9.  
    10.  
    11. .text:00792660     ; A *__stdcall A_ctor(A *this)
    12. .text:00792660     A_ctor proc near              
    13. .text:00792660
    14. .text:00792660     this            = dword ptr  4
    15. .text:00792660
    16. .text:00792660     this_0 = ebp
    17. .text:00792660 000                 push    ebx
    18. .text:00792661 004                 push    this_0
    19. .text:00792662 008                 mov     this_0, [esp+8+this]
    20. .text:00792666 008                 push    esi
    21. .text:00792667 00C                 mov     esi, ds:InitializeCriticalSection_0
    22. .text:0079266D 00C                 push    edi
    23. .text:0079266E 010                 xor     ebx, ebx
    24. .text:00792670 010                 lea     edi, [this_0+1Bh]
    25. .text:00792673 010                 mov     dword ptr [this_0+4], offset aModule ; "module"
    26. .text:0079267A 010                 mov     [this_0+8], bl
    27. .text:0079267D 010                 mov     byte ptr [this_0+12h], 1
    28. .text:00792681 010                 mov     [this_0+9], bl
    29. .text:00792684 010                 mov     [this_0+0Ah], ebx
    30. .text:00792687 010                 mov     [this_0+0Eh], ebx
    31. .text:0079268A 010                 mov     dword ptr [this_0+13h], offset off_F1ACB0
    32. .text:00792691 010                 mov     dword ptr [this_0+17h], offset `__vtable__'[XBase]
    33. .text:00792698 010                 lea     eax, [edi+3]
    34. .text:0079269B 010                 and     eax, 0FFFFFFFCh
    35. .text:0079269E 010                 mov     dword ptr [this_0+0], offset off_F1AA50
    36. .text:007926A5 010                 mov     dword ptr [this_0+13h], offset off_F1AAD0
    37. .text:007926AC 010                 mov     dword ptr [this_0+17h], offset `__vtable__'[X]
    38. .text:007926B3 010                 push    eax             ; lpCriticalSection
    39. .text:007926B4 014                 mov     dword ptr [edi+28h], offset aObjectmanager ; "ObjectManager"
    40. .text:007926BB 014                 call    esi ; InitializeCriticalSection_0
    вот кусок вызывающей функции и кусок вызывемой. на первый взгляд выглядит, что по смещению 0x17 расположен указатель на таблицу виртальных методов