2010-11-19 14 views
8

मैं कुछ असेंबली कोड को समझने की कोशिश कर रहा हूं और कुछ पंक्तियों को छोड़कर इसे पूरा करने में कामयाब रहा हूं। मैं अंदर जो कुछ भी हो रहा है उसे समझने में सक्षम हूं लेकिन कोड की शुरुआत और समाप्ति पर क्या (और क्यों) हो रहा है, यह पूरी तरह से समझने में सक्षम नहीं हूं। क्या कोई इस पर कुछ प्रकाश डाला सकता है?कुछ असेंबली स्टेटमेंट्स के उद्देश्य को समझना

int main() { 
    int a, b; 
    a = 12; 
    b = 20; 
    b = a + 123; 
    return 0; 
} 

disassembled संस्करण:

8048394:8d 4c 24 04   lea 0x4(%esp),%ecx    ; ?? 
8048398:83 e4 f0    and $0xfffffff0,%esp   ; ?? 
804839b:ff 71 fc    pushl -0x4(%ecx)     ; ?? 
804839e:55     push %ebp      ; Store the Base pointer 
804839f:89 e5    mov %esp,%ebp     ; Initialize the Base pointer with the stack pointer 
80483a1:51     push %ecx      ; ?? 
80483a2:83 ec 4c    sub $0x4c,%esp     ; ?? 
80483a5:c7 45 f8 0c 00 00 00 movl $0xc,-0x8(%ebp)    ; Move 12 into -0x8(%ebp) 
80483ac:c7 45 f4 14 00 00 00 movl $0x14,-0xc(%ebp)   ; Move 20 into -0xc(%ebp) 
80483b3:8b 45 f8    mov -0x8(%ebp),%eax    ; Move [email protected](%ebp) into eax 
80483b6:83 c0 7b    add $0x7b,%eax     ; Add 123 to [email protected] 
80483b9:89 45 f4    mov %eax,-0xc(%ebp)    ; Store the result into [email protected](%ebp) 
80483bc:b8 00 00 00 00  mov $0x0,%eax     ; Move 0 into eax 
80483c1:83 c4 10    add $0x10,%esp     ; ?? 
80483c4:59     pop %ecx      ; ?? 
80483c5:5d     pop %ebp      ; ?? 
80483c6:8d 61 fc    lea -0x4(%ecx),%esp    ; ?? 
+0

आपको स्टैक पर कहां है, इसकी तस्वीर खींचने में मदद मिलती है ... –

+0

टिप्पणियों में ऑपकोड के लिए केवल अंग्रेज़ी नाम लिखने से आपको बहुत मदद नहीं मिलेगी। उन्हें और अधिक "उच्च स्तर" बनाने का प्रयास करें। और, यदि आप वास्तव में dissasembly से कुछ सीखना चाहते हैं, तो मानव कोड का प्रयास करें, संकलक नहीं। – ruslik

+1

आमतौर पर शुरुआत और अंत में सामान जेनेरिक स्टैक सेटअप कोड है। आवंटन और संरेखण और ऐसे। – zdav

उत्तर

26

ढेर नीचे बढ़ता है। एक push स्टैक पॉइंटर (एसएसपी) से घटाता है और pop एएसपी में जोड़ता है। आपको इसे समझने के लिए इसे ध्यान में रखना होगा।

8048394:8d 4c 24 04   lea 0x4(%esp),%ecx    ; ?? 

ली = लोड प्रभावी पता

यह बात यह है कि ढेर में 4 बाइट झूठ का पता बचाता है। चूंकि यह 32 बिट (4 बाइट शब्द) x86 कोड है जिसका मतलब स्टैक पर दूसरा आइटम है। चूंकि यह एक फ़ंक्शन का कोड है (इस मामले में मुख्य) स्टैक के शीर्ष पर स्थित 4 बाइट्स रिटर्न पता है।

8048398:83 e4 f0    and $0xfffffff0,%esp   ; ?? 

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

804839b:ff 71 fc    pushl -0x4(%ecx)     ; ?? 

के बाद से ECX ढेर के पिछले ऊपर से वापसी पता के दूसरे पक्ष पर बात के सूचक के रूप से पहले लोड किया गया था, तो के बाद से यह एक -4 सूचक है इस वापसी पता करने के लिए वापस करने के लिए संदर्भित करता है वर्तमान कार्य को स्टैक के शीर्ष पर वापस धक्का दिया जा रहा है ताकि मुख्य रूप से मुख्य रूप से वापस आ सकें। (पुश जादू है और एक ही निर्देश में रैम में अलग-अलग स्थानों से लोड और स्टोर करने में सक्षम होने लगता है)।

804839e:55     push %ebp      ; Store the Base pointer 
804839f:89 e5    mov %esp,%ebp     ; Initialize the Base pointer with the stack pointer 
80483a1:51     push %ecx      ; ?? 
80483a2:83 ec 4c    sub $0x4c,%esp     ; ?? 

यह ज्यादातर मानक फ़ंक्शन प्रस्तावना है (पिछली सामग्री मुख्य के लिए विशेष थी)। यह एक स्टैक फ्रेम (ईबीपी और एएसपी के बीच क्षेत्र) बना रहा है जहां स्थानीय चर लाइव रह सकते हैं। ईबीपी को धक्का दिया जाता है ताकि पुराने स्टैक फ्रेम को एपिलॉग (वर्तमान फ़ंक्शन के अंत में) में बहाल किया जा सके।

80483a5:c7 45 f8 0c 00 00 00 movl $0xc,-0x8(%ebp)    ; Move 12 into -0x8(%ebp) 
80483ac:c7 45 f4 14 00 00 00 movl $0x14,-0xc(%ebp)   ; Move 20 into -0xc(%ebp) 
80483b3:8b 45 f8    mov -0x8(%ebp),%eax    ; Move [email protected](%ebp) into eax 
80483b6:83 c0 7b    add $0x7b,%eax     ; Add 123 to [email protected] 
80483b9:89 45 f4    mov %eax,-0xc(%ebp)    ; Store the result into [email protected](%ebp) 

80483bc:b8 00 00 00 00  mov $0x0,%eax     ; Move 0 into eax 

ईएक्स वह है जहां पूर्णांक फ़ंक्शन रिटर्न मान संग्रहीत किए जाते हैं। यह मुख्य से 0 वापस करने के लिए स्थापित है।

80483c1:83 c4 10    add $0x10,%esp     ; ?? 
80483c4:59     pop %ecx      ; ?? 
80483c5:5d     pop %ebp      ; ?? 
80483c6:8d 61 fc    lea -0x4(%ecx),%esp    ; ?? 

यह कार्य epilogue है। शुरुआत में अजीब स्टैक संरेखण कोड की वजह से समझना अधिक कठिन है। मुझे थोड़ी सी परेशानी हो रही है कि इस समय प्रस्तावना की तुलना में स्टैक को कम राशि से क्यों समायोजित किया जा रहा है।

यदि यह स्पष्ट है कि यह विशेष कोड ऑप्टिमाइज़ेशन के साथ संकलित नहीं किया गया था।यदि वहां मौजूद थे तो शायद वहां बहुत कुछ नहीं होगा क्योंकि संकलक देख सकता है कि भले ही यह आपके main में सूचीबद्ध गणित नहीं करता है, कार्यक्रम का अंतिम परिणाम समान है। उन कार्यक्रमों के साथ जो वास्तव में कुछ करते हैं (दुष्प्रभाव या परिणाम होते हैं) कभी-कभी हल्के ढंग से अनुकूलित कोड (-O1 या -0s gcc के लिए तर्क) को पढ़ने में आसान होता है।

एक कंपाइलर द्वारा उत्पन्न असेंबली पढ़ने अक्सर उन कार्यों के लिए बहुत आसान है जो main नहीं हैं। यदि आप कोड को समझने के लिए पढ़ना चाहते हैं तो अपने आप को एक ऐसा फ़ंक्शन लिखें जो परिणाम उत्पन्न करने के लिए कुछ तर्क लेता है या जो वैश्विक चर पर काम करता है, और आप इसे बेहतर समझ पाएंगे।

एक और चीज जो शायद आपकी मदद करेगी, केवल जीसीसी आपके लिए असेंबली फाइलें उत्पन्न करने के बजाय, आपके लिए असेंबली फाइलें उत्पन्न करेगी। -S ध्वज इसे उत्पन्न करने के लिए कहता है (लेकिन अन्य फ़ाइलों को उत्पन्न नहीं करने के लिए), और अंत में .s के साथ असेंबली फ़ाइलों को नामित करता है। अलग-अलग संस्करणों से पढ़ने के लिए यह आपके लिए आसान होना चाहिए।

+0

आपके समय के लिए धन्यवाद। बहुत विस्तृत स्पष्टीकरण। मुझे इसकी ही खोज थी। – Legend

+0

प्रश्न 1: पहले 4 बाइट्स क्यों जोड़ें, फिर इसे घटाएं। क्यों न केवल 'ली (% esp),% ecx' तो' pushl (% ecx) '? प्रश्न 2: क्या इस तरह के संरेखण को अक्षम करने के लिए कोई ध्वज है? ('-फनो-संरेखण-कार्य' काम नहीं करता है)। – Tony

6

सुनिश्चित नहीं हैं कि क्यों संकलक यह सब सामान है, लेकिन यहाँ मैं क्या समझ सकती है:

8048394:8d 4c 24 04   lea 0x4(%esp),%ecx    ; ecx := esp+4 
8048398:83 e4 f0    and $0xfffffff0,%esp   ; align the stack to 16 bytes 
804839b:ff 71 fc    pushl -0x4(%ecx)     ; push [ecx-4] ([esp]) 
80483a1:51     push %ecx      ; push ecx 
80483a2:83 ec 4c    sub $0x4c,%esp     ; allocate 19 dwords on stack 
80483c1:83 c4 10    add $0x10,%esp     ; deallocate 4 dwords from stack 
80483c4:59     pop %ecx      ; restore ecx 
80483c5:5d     pop %ebp      ; and ebp 
80483c6:8d 61 fc    lea -0x4(%ecx),%esp    ; esp := [ecx-4] 
+1

स्पष्टीकरण के लिए धन्यवाद। – Legend

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