Подобрать параметры компилятора

Тема в разделе "WASM.RESEARCH", создана пользователем _Juicy, 10 мар 2006.

  1. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Имеется процедура
    Код (Text):
    1. 00401000   push    esi
    2. 00401001   push    edi
    3. 00401002   mov     esi, [esp+0Ch]
    4. 00401006   cmp     esi, 1
    5. 00401009   jle     00401023
    6. 0040100B   mov     edi, [esp+10h]
    7. 0040100F   dec     esi
    8. 00401010   add     edi, 4
    9. 00401013   mov     eax, [edi]
    10. 00401015   add     edi, 4
    11. 00401018   push    eax
    12. 00401019   push    eax
    13. 0040101A   call    ds:_import_
    14. 00401020   dec     esi
    15. 00401021   jnz     00401013
    16. 00401023   pop     edi
    17. 00401024   pop     esi
    18. 00401025   retn    8
    19.  




    Хочется переписать все это дело на си и подогнать параметры компиляции/оптимизации так, чтобы код получался идентичный. Максимум, что удалось сделать:
    Код (Text):
    1.     if (arg1 > 1)
    2.     {
    3.         arg1--;
    4.         arg2++;
    5.         do {
    6.             _import_ (*arg2, *arg2);
    7.             arg2++;
    8.         }
    9.         while (arg1--);
    10.     }
    11.  


    на VC<sup>R</sup>6.0 c параметрами /Og /Os /Oy дает
    Код (Text):
    1. 00401000   push        edi
    2. 00401001   mov         edi,[esp+8]
    3. 00401005   cmp         edi,1
    4. 00401008   jle         00401028
    5. 0040100A   push        esi
    6. 0040100B   mov         esi,dword ptr [esp+10h]
    7. 0040100F   dec         edi
    8. 00401010   add         esi,4
    9. 00401013   mov         eax,dword ptr [esi]
    10. 00401015   push        eax
    11. 00401016   push        eax
    12. 00401017   call        ds:_import_
    13. 0040101D   add         esi,4
    14. 00401020   mov         eax,edi
    15. 00401022   dec         edi
    16. 00401023   test        eax,eax
    17. 00401025   jne         00401013
    18. 00401027   pop         esi
    19. 00401028   pop         edi
    20. 00401029   ret         8
    21.  




    Что еще можно сделать с кодом/компилятором, чтобы добиться схожести?
     
  2. OlegA11

    OlegA11 New Member

    Публикаций:
    0
    Регистрация:
    12 фев 2006
    Сообщения:
    102
    А что, нельзя просто напросто использовать ассемблерную вставку?
     
  3. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Можно, но интересно не это.
     
  4. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    код направильно восстановлен. Должно быть примерно так:
    Код (Text):
    1.  
    2. extern _stdcall _import_(long p1, long p2);
    3.  
    4. void _stdcall func(int arg1, long *arg2)
    5. {
    6.     int i;
    7.     for(i = arg1; i > 1; --i, arg2++)
    8.         _import_ (*arg2, *arg2);
    9.  
    10. }
    11.  




    это компилится с указанными опциями в:
    Код (Text):
    1.  
    2.     mov eax, DWORD PTR _arg1$[esp-4]
    3.     cmp eax, 1
    4.     jle SHORT $L278
    5.     push    esi
    6.     mov esi, DWORD PTR _arg2$[esp]
    7.     push    edi
    8.     lea edi, DWORD PTR [eax-1]
    9. $L276:
    10.     mov eax, DWORD PTR [esi]
    11.     push    eax
    12.     push    eax
    13.     call    ?_import_@@YGHJJ@Z          ; _import_
    14.     add esi, 4
    15.     dec edi
    16.     jne SHORT $L276
    17.     pop edi
    18.     pop esi
    19. $L278:
    20.     ret 8
    21.  




    что гораздо ближе к оригиналу.

    ps: Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
     
  5. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Squash



    Вряд ли оригинал содержал столь запутанные конструкции. первый add edi,4 (который забыл infern0) - это обычное разворачивание первой итерации цикла. Однако последние версии MSVC что-то не захотели так делать с закоментированным вариантом:
    Код (Text):
    1.  
    2. extern "C" void __stdcall import_(void * p1, void * p2);
    3.  
    4. void __stdcall fun(int count, void ** p)
    5. {
    6. /*
    7.   for ( ; count > 1; --count )
    8.   {
    9.     ++p;
    10.     import_(*p, *p);
    11.   }
    12. */
    13.   for ( ; count > 1; ++p, --count )
    14.     import_(p[1], p[1]);
    15. }


    Версиями 7.10.4035 и 8.00.50727.42 компилируется в
    Код (Text):
    1.  
    2. ; Function compile flags: /Ogspy
    3. _TEXT   SEGMENT
    4. _count$ = 8                     ; size = 4
    5. _p$ = 12                        ; size = 4
    6. ?fun@@YGXHPAPAX@Z PROC                  ; fun
    7.     mov eax, DWORD PTR _count$[esp-4]
    8.     cmp eax, 1
    9.     jle SHORT $LN1@fun
    10.     push    esi
    11.     mov esi, DWORD PTR _p$[esp]
    12.     push    edi
    13.     add esi, 4
    14.     lea edi, DWORD PTR [eax-1]
    15. $LL3@fun:
    16.     mov eax, DWORD PTR [esi]
    17.     push    eax
    18.     push    eax
    19.     call    _import_@8
    20.     add esi, 4
    21.     dec edi
    22.     jne SHORT $LL3@fun
    23.     pop edi
    24.     pop esi
    25. $LN1@fun:
    26.     ret 8
    27. ?fun@@YGXHPAPAX@Z ENDP                  ; fun
     
  6. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    infern0, S_T_A_S_

    Спасибо. Попробовать for(;;) почему-то в голову не пришло :dntknw:

    А не подскажет ли кто-нибудь, какая могла быть версия компилятора, если это 96-ой год?