2016-06-23 13 views
6

मैं 32-bit x86 आर्किटेक्चर पर बाइनरी की ओर कुछ रिवर्स इंजीनियरिंग कार्य कर रहा हूं।मेमोरी आवंटन अनुकूलन: ढेर से ढेर

हाल ही में मुझे C स्रोत कोड से असेंबली प्रोग्राम में कुछ रोचक अनुकूलन मिले।

उदाहरण के लिए, मूल स्रोत कोड की तरह (इस स्रोत कोड openssl library से है):

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. 

:

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

और संकलन (gcc version 4.8.4 -O3) के बाद, विधानसभा कोड इस तरह है मेरे आश्चर्य करने के लिए, buf वास्तव में ढेर पर आवंटित किया जाता है !!! यह मेरे लिए ढेर संभाजक के लिए एक अनुकूलन की तरह लगता है, लेकिन मुझे यकीन है कि नहीं हूँ।

तो मेरा प्रश्न यह है कि क्या उपर्युक्त अनुकूलन (मॉलोक -> स्टैक आवंटन) किसी के लिए familar लगता है? क्या इस का कोई मतलब निकलता है? क्या कोई इस तरह के अनुकूलन पर कुछ मैनुअल/विनिर्देश प्रदान कर सकता है?

+0

मॉलोक कॉल कहां है? \ –

+1

यह मुझे नए जेवीएम में एस्केप विश्लेषण का बहुत याद दिलाता है। https://en.wikipedia.org/wiki/Escape_analysis यदि स्मृति फ़ंक्शन कॉल के बाहर कभी नहीं रहती है, तो इसे सुरक्षित रूप से स्टैक से आवंटित किया जा सकता है। यदि आपके पास अपने ढेर में जगह है तो यह ऑपरेशन की एक बहुत तेज़ आवंटन/मुक्त जोड़ी होगी। – Sam

+0

मुझे लगता है कि ढेर एक सामान्य वृक्ष संरचना है। गहराई की खोज विधि के साथ ढेर को घुमाने के द्वारा, तत्वों को एक ढेर के क्रम से अनुक्रम में देखा गया। –

उत्तर

5

से 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; 

ध्यान दें कि 0xbff प्रणाली है कि इसे समर्थन पर 3071. के बराबर है, alloca आवंटन ढेर है। यह GNU version का सत्य है, जिसका उपयोग Linux द्वारा किया जाता है, और BSD implementations ने इस एपीआई को 32V यूनिक्स से AT & टी (according to FreeBSD) से कॉपी किया है।

आपने केवल 639 लाइन पर देखा। लेकिन यदि alloca परिभाषित किया गया है, तो सी कोड आपकी असेंबली तक मेल खाता है।

आवंटन को अक्सर अस्थायी बफर के लिए malloc का उपयोग करने के खर्च से बचने के लिए उपयोग किया जाता है यदि आवंटन अपेक्षाकृत छोटा है। सी .1 999 के लिए, इसके बजाय एक वीएलए का उपयोग किया जा सकता है (सी.2011 के बाद से, वीएलए एक वैकल्पिक सुविधा है)।

कभी कभी, अनुकूलन बस कुछ उचित छोटा सा आकार के एक निश्चित आकार बफर उपयोग करता है। उदाहरण के लिए:

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

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

आपकी मदद के लिए धन्यवाद ... मैं इस पल में इतनी लापरवाह हूं ... – computereasy

संबंधित मुद्दे