Шаг 122.
Оптимизация кода: транслятор Borland C++ 4.5

    На этом шаге мы рассмотрим как оптимизирует код транслятор Borland C++ 4.5.

    Ранее мы пытались восстановить исходный текст программы по ассемблерному коду. Насколько это удалось, можно выяснить, сравнив получившийся текст с исходным. Причина отличия двух текстов программ заключается в том, что транслятор, кроме всего прочего, производит еще оптимизацию кода. Результат оптимизации - принципиальная невозможность восстановить исходный текст по исполняемому коду. Можно, однако, получить программный текст, правильно описывающий алгоритм исполнения. Можно просто понять то, что делает данный код.

    Рассмотрим небольшую программу на С.

#include <iostream.h>
#include <conio.h>
void main()
{
  int i;
  char a[10];
  char b[11];
  for(i=0; i<10; i++)
  {
	 a[i]='a';
	 *(b+i)='a';
	 cout << a[i] << " " << b[i] << endl;
  }
  getch();
}
Текст этой программы можно взять здесь.

    Приведем текст дизассемблированной программы, полученной с помощью IDA PRO:

CODE:00410074 _main           proc near               ; DATA XREF: DATA:00420044
CODE:00410074 
CODE:00410074 var_18          = byte ptr -18h
CODE:00410074 var_C           = byte ptr -0Ch
CODE:00410074 argc            = dword ptr  8
CODE:00410074 argv            = dword ptr  0Ch
CODE:00410074 envp            = dword ptr  10h
CODE:00410074 
CODE:00410074                 push    ebp
CODE:00410075                 mov     ebp, esp
CODE:00410077                 add     esp, 0FFFFFFE8h
CODE:0041007A                 push    ebx
CODE:0041007B                 push    esi
CODE:0041007C                 xor     ebx, ebx
CODE:0041007E 
CODE:0041007E loc_41007E:                             ; CODE XREF: _main+52
CODE:0041007E                 mov     [ebp+ebx+var_C], 61h
CODE:00410083                 mov     [ebp+ebx+var_18], 61h
CODE:00410088                 mov     al, [ebp+ebx+var_18]
CODE:0041008C                 push    eax
CODE:0041008D                 mov     al, [ebp+ebx+var_C]
CODE:00410091                 push    eax
CODE:00410092                 push    ds:_cout
CODE:00410098                 call    @ostream@$blsh$qc ; ostream::operator<<(char)
CODE:0041009D                 add     esp, 8
CODE:004100A0                 mov     esi, eax
CODE:004100A2                 push    0
CODE:004100A4                 push    offset unk_420070
CODE:004100A9                 push    esi
                                               ; ostream::outstr(char *,char *)
CODE:004100AA                 call    @ostream@outstr$qpxct1 
CODE:004100AF                 add     esp, 0Ch
CODE:004100B2                 push    esi
CODE:004100B3                 call    @ostream@$blsh$qc ; ostream::operator<<(char)
CODE:004100B8                 add     esp, 8
CODE:004100BB                 push    eax
CODE:004100BC                 call    @endl$qr7ostream ; endl(ostream &)
CODE:004100C1                 pop     ecx
CODE:004100C2                 inc     ebx
CODE:004100C3                 cmp     ebx, 0Ah
CODE:004100C6                 jl      short loc_41007E
CODE:004100C8                 call    _getch
CODE:004100CD                 pop     esi
CODE:004100CE                 pop     ebx
CODE:004100CF                 mov     esp, ebp
CODE:004100D1                 pop     ebp
CODE:004100D2                 retn
CODE:004100D2 _main           endp

    Видно, что здесь оптимизация отсутствует. По такому тексту достаточно просто восстановить исходную С-программу.

    На следующем шаге мы рассмотрим работу транслятора Visual C++ 6.0.




Предыдущий шаг Содержание Следующий шаг