Имеется процедура Код (Text): 00401000 push esi 00401001 push edi 00401002 mov esi, [esp+0Ch] 00401006 cmp esi, 1 00401009 jle 00401023 0040100B mov edi, [esp+10h] 0040100F dec esi 00401010 add edi, 4 00401013 mov eax, [edi] 00401015 add edi, 4 00401018 push eax 00401019 push eax 0040101A call ds:_import_ 00401020 dec esi 00401021 jnz 00401013 00401023 pop edi 00401024 pop esi 00401025 retn 8 Хочется переписать все это дело на си и подогнать параметры компиляции/оптимизации так, чтобы код получался идентичный. Максимум, что удалось сделать: Код (Text): if (arg1 > 1) { arg1--; arg2++; do { _import_ (*arg2, *arg2); arg2++; } while (arg1--); } на VC<sup>R</sup>6.0 c параметрами /Og /Os /Oy дает Код (Text): 00401000 push edi 00401001 mov edi,[esp+8] 00401005 cmp edi,1 00401008 jle 00401028 0040100A push esi 0040100B mov esi,dword ptr [esp+10h] 0040100F dec edi 00401010 add esi,4 00401013 mov eax,dword ptr [esi] 00401015 push eax 00401016 push eax 00401017 call ds:_import_ 0040101D add esi,4 00401020 mov eax,edi 00401022 dec edi 00401023 test eax,eax 00401025 jne 00401013 00401027 pop esi 00401028 pop edi 00401029 ret 8 Что еще можно сделать с кодом/компилятором, чтобы добиться схожести?
код направильно восстановлен. Должно быть примерно так: Код (Text): extern _stdcall _import_(long p1, long p2); void _stdcall func(int arg1, long *arg2) { int i; for(i = arg1; i > 1; --i, arg2++) _import_ (*arg2, *arg2); } это компилится с указанными опциями в: Код (Text): mov eax, DWORD PTR _arg1$[esp-4] cmp eax, 1 jle SHORT $L278 push esi mov esi, DWORD PTR _arg2$[esp] push edi lea edi, DWORD PTR [eax-1] $L276: mov eax, DWORD PTR [esi] push eax push eax call ?_import_@@YGHJJ@Z ; _import_ add esi, 4 dec edi jne SHORT $L276 pop edi pop esi $L278: ret 8 что гораздо ближе к оригиналу. ps: Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Squash Вряд ли оригинал содержал столь запутанные конструкции. первый add edi,4 (который забыл infern0) - это обычное разворачивание первой итерации цикла. Однако последние версии MSVC что-то не захотели так делать с закоментированным вариантом: Код (Text): extern "C" void __stdcall import_(void * p1, void * p2); void __stdcall fun(int count, void ** p) { /* for ( ; count > 1; --count ) { ++p; import_(*p, *p); } */ for ( ; count > 1; ++p, --count ) import_(p[1], p[1]); } Версиями 7.10.4035 и 8.00.50727.42 компилируется в Код (Text): ; Function compile flags: /Ogspy _TEXT SEGMENT _count$ = 8 ; size = 4 _p$ = 12 ; size = 4 ?fun@@YGXHPAPAX@Z PROC ; fun mov eax, DWORD PTR _count$[esp-4] cmp eax, 1 jle SHORT $LN1@fun push esi mov esi, DWORD PTR _p$[esp] push edi add esi, 4 lea edi, DWORD PTR [eax-1] $LL3@fun: mov eax, DWORD PTR [esi] push eax push eax call _import_@8 add esi, 4 dec edi jne SHORT $LL3@fun pop edi pop esi $LN1@fun: ret 8 ?fun@@YGXHPAPAX@Z ENDP ; fun
infern0, S_T_A_S_ Спасибо. Попробовать for(; почему-то в голову не пришло А не подскажет ли кто-нибудь, какая могла быть версия компилятора, если это 96-ой год?