2010-03-08 5 views
7

एएसएम के शुरुआती के रूप में, मैं सीखने के लिए जीसीसी-एस जेनरेट एएसएम कोड की जांच कर रहा हूं।एक विधि कॉल करते समय linux पर स्टैक के लिए gcc 4.x डिफ़ॉल्ट आरक्षित 8 बाइट क्यों?

एक विधि कॉल करते समय स्टैक के लिए जीसीसी 4.x डिफ़ॉल्ट आरक्षित 8 बाइट क्यों?

func18 कोई रिक्त कार्य नहीं है जिसमें कोई वापसी नहीं है कोई स्थानीय var परिभाषित नहीं है। मुझे पता नहीं लगाया जा सकता है कि क्यों 8 बाइट आरक्षित हैं (न ही किसी फोरम/साइट के कारण के लिए उल्लेख है, पीपीएल इसे मानने के लिए लगता है) क्या यह% ebp सिर्फ धक्का है? या वापसी प्रकार ?! कई thx!

 .globl _func18 
    _func18: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $8, %esp 
    .text 
+0

वास्तव में, इनमें से कोई भी निर्देश समझ में नहीं आता है ... किसी भी स्थानीय चर के बिना एक फ़ंक्शन को फ्रेम सूचक – Martin

+0

सेट करने की आवश्यकता नहीं है, यह शायद अनुकूलन स्तर पर निर्भर करता है। क्या आप फ़ंक्शन के लिए पूर्ण जेनरेट कोड शामिल कर सकते हैं? –

+2

वापसी का पता और ढेर फ्रेम सूचक के लिए यह जगह नहीं है? – jdizzle

उत्तर

0

ऊपर उल्लिखित समृद्ध के रूप में, यह सब कुछ अनुकूलन के कारण है, नीचे दिखा रहा है। लेकिन फिर भी मुझे नहीं पता कि क्यों 8 बाइट आरक्षित कुछ अनुकूलित है ?!

मूल ग

void func18() {} 
int main() {return 0;} 

अनुकूलन झंडा बिना संकलन निर्दिष्ट

.text                     
.globl _func18 
_func18: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $8, %esp 
    leave 
    ret 
.globl _main 
_main:                      
    pushl %ebp 
    movl %esp, %ebp 
    subl $8, %esp 
    movl $0, %eax 
    leave 
    ret 
    .subsections_via_symbols 

-Os अनुकूलन ध्वज के साथ , कोई और अधिक ढेर आरक्षित

.text 
.globl _func18 
_func18: 
    pushl %ebp 
    movl %esp, %ebp 
    leave 
    ret 
.globl _main 
_main: 
    pushl %ebp 
    xorl %eax, %eax 
    movl %esp, %ebp 
    leave 
    ret 
    .subsections_via_symbols 
+2

अपने प्रश्न में यह शब्दों में कहें, एक अलग जवाब – moo

0

पता लगाने का आसान तरीका: क्या आप खाली पैरामीटर को एक पैरामीटर के साथ एक और फ़ंक्शन कॉल करते हैं। यदि पैरामीटर सीधे ढेर (कोई धक्का नहीं) पर संग्रहीत किया जाता है, तो यही अतिरिक्त जगह है।

+0

मैंने पहले की कोशिश की में नहीं, यह इसके साथ – nikcname

8

कुछ निर्देशों को कुछ डेटा प्रकारों को 16-बाइट सीमा (विशेष रूप से, एसएसई डेटा प्रकार __m128) के साथ गठबंधन करने की आवश्यकता होती है। इस आवश्यकता को पूरा करने के लिए, जीसीसी यह सुनिश्चित करता है कि स्टैक प्रारंभ में 16-बाइट गठबंधन है, और 16 बाइट्स के गुणकों में स्टैक स्पेस आवंटित करता है। यदि केवल 4-बाइट रिटर्न पता और 4-बाइट फ्रेम पॉइंटर को धक्का दिया जाना चाहिए, तो स्टैक को 16-बाइट सीमा पर गठबंधन रखने के लिए 8 अतिरिक्त बाइट की आवश्यकता होती है। हालांकि, अगर जीसीसी निर्धारित करता है कि अतिरिक्त संरेखण अनावश्यक है (यानी फैंसी डेटा प्रकारों का उपयोग नहीं किया जाता है और कोई बाहरी कार्य नहीं कहा जाता है), तो यह स्टैक को संरेखित करने के लिए उपयोग किए गए किसी भी अतिरिक्त निर्देश को छोड़ सकता है। इसे निर्धारित करने के लिए आवश्यक विश्लेषण के लिए कुछ अनुकूलन पास किए जाने की आवश्यकता हो सकती है।

विकल्प -mpreferred-stack-boundary=num विकल्प के लिए जीसीसी दस्तावेज भी देखें।

+0

THX निशान संबंधित नहीं लगता है, तो यह सभी डेटा alignement के लिए जब SSE के साथ अनुकूलन बहुत समझदार के रूप में मैं अनुकूलन अक्षम है और subl $ 8 % esp चला गया है। जीसीसी रेफरी बहुत उपयोगी है !!! केवल 1 चीज, जबकि मैं -फ्रेंडर्ड-स्टैक-सीमा के आस-पास, आरक्षण केवल 3 से 4 के बीच, 4 से 4 तक, यह 8 बाइट्स के साथ चिपक जाता है, मैंने सोचा कि आरक्षण 20 बाइट्स होना चाहिए, नहीं? – nikcname

+0

यदि आपने -mpreferred-stack-border = 12 का उपयोग किया है, तो बाहरी कार्यों को कॉल करने वाले किसी भी फ़ंक्शन में यह 2^12 = 4096 बाइट्स के गुणकों में स्टैक स्पेस आवंटित करेगा। यदि आप किसी भी बाहरी कार्यों को नहीं बुला रहे हैं तो यह अक्सर यह पता लगाने में सक्षम होगा कि बनाए रखने वाले कोड के लिए संरेखण की आवश्यकता नहीं है (आपके सटीक जीसीसी संस्करण, विकल्प और लक्ष्य आर्किटेक्चर पर निर्भर करता है)। – mark4o

+0

तो आपका मतलब बाहरी func को कॉल किए बिना func मामले में है, gcc बस डिफ़ॉल्ट रूप से 8 बाइट्स के साथ चिपके रहें? – nikcname

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