2016-06-23 22 views
6

Wykonuję niektóre zadania inżynierii odwrotnej w kierunku plików binarnych w architekturze 32-bit x86.Optymalizacja alokacji pamięci: od sterty do stosu

Ostatnio znalazłem kilka interesujących optymalizacji z kodu źródłowego C do programu montażu.

Na przykład, oryginalny kod źródłowy jest podobne (kod źródłowy z openssl library)

powerbufFree = (unsigned char *)malloc(powerbufLen); 

A po kompilacji (gcc version 4.8.4 -O3) kod Zespół jest tak:

807eaa0: cmp eax, 0xbff       # eax holds the length of the buf. 
807eaa5: mov dword ptr [ebp-0x68], eax   # store the length of powerbuf on the stack 
807eaa8: jnle 0x807ec60       # 0x807ec60 refers to the malloc 
807eaae: mov edx, eax 
807eab0: add eax, 0x5e 
807eab3: and eax, 0xfffffff0 
807eab6: sub esp, eax 
807eab8: lea eax, ptr [esp+0x23] 
807eabc: and eax, 0xffffffc0 
807eabf: add eax, 0x40 
807ead3: mov dword ptr [ebp-0x60], eax # store the base addr of the buf on the stack. 

Ku mojemu zaskoczeniu, buf jest rzeczywiście przydzielany na stosie !!! Wydaje się, że dla mnie jest to optymalizacja dla przydziału sterty, ale nie jestem pewien.

Oto moje pytanie, czy powyższa optymalizacja (malloc -> alokacja stosu) wydaje się być znana każdemu? Czy jest sens? Czy ktokolwiek mógłby podać instrukcję/specyfikację takiej optymalizacji?

+0

gdzie jest wywołanie malloc? \ –

+1

To bardzo przypomina mi Escape Analysis w nowszych maszynach JVM. https://en.wikipedia.org/wiki/Escape_analysis Jeśli pamięć nigdy nie będzie żyła poza wywołaniem funkcji, może być bezpiecznie przydzielona ze stosu. Jeśli masz miejsce w swoim stosie, będzie to znacznie szybsza alokacja/wolna para operacji. – Sam

+0

Myślę, że sterty to ogólna struktura drzewa. Przemierzając stertę za pomocą metody Głębokość Poszukiwania, elementy odwiedzane są w kolejności od kolejności stosu. –

Odpowiedz

5

Z source of bn_exp.c:

0634 #ifdef alloca 
0635  if (powerbufLen < 3072) 
0636   powerbufFree = alloca(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); 
0637  else 
0638 #endif 
0639  if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) 
0640   goto err; 

Zauważ, że 0xbff jest równa 3071. W systemach, które go obsługują, alloca kumuluje alokacji. Dotyczy to modelu GNU version, który jest używany przez Linux i skopiował ten interfejs API z 32 V UNIX z AT & T (according to FreeBSD).

Spojrzałaś tylko na linię 639. Ale jeśli zdefiniowano alloca, kod C pasuje do twojego zespołu.

Sama optymalizacja jest często używana w celu uniknięcia wydatków związanych z używaniem tymczasowego bufora, jeśli alokacja jest względnie mała. W przypadku C.1999 można użyć VLA (od C.2011, VLA jest opcjonalną funkcją).

Czasami optymalizacja używa tylko bufora o stałym rozmiarze o pewnym rozsądnym małym rozmiarze. Na przykład:

char tmp_buf[1024]; 
char *tmp = tmp_buf; 

if (bytes_needed > 1024) { 
    tmp = malloc(bytes_needed); 
} 
/* ... */ 
if (tmp != tmp_buf) { 
    free(tmp); 
} 
+0

Dziękuję za pomoc ... W tej chwili jestem nieostrożny ... – computereasy

Powiązane problemy