2010-10-26 15 views
8
$ gcc -O2 -S test.c -----------------------(1) 
     .file "test.c" 
    .globl accum 
     .bss 
     .align 4 
     .type accum, @object 
     .size accum, 4 
    accum: 
     .zero 4 
     .text 
     .p2align 2,,3 
    .globl sum 
     .type sum, @function 
    sum: 
     pushl %ebp 
     movl %esp, %ebp 
     movl 12(%ebp), %eax 
     addl 8(%ebp), %eax 
     addl %eax, accum 
     leave 
     ret 
     .size sum, .-sum 
     .p2align 2,,3 
    .globl main 
     .type main, @function 
    main: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $8, %esp 
     andl $-16, %esp 
     subl $16, %esp 
     pushl $11 
     pushl $10 
     call sum 
     xorl %eax, %eax 
     leave 
     ret 
     .size main, .-main 
     .section .note.GNU-stack,"",@progbits 
     .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)" 

यह इस सी कार्यक्रम से उत्पन्न एक विधानसभा कोड है:का विश्लेषण विधानसभा कोड

$objdump -d test.o -------------------------(2) 

test.o:  file format elf32-i386 

Disassembly of section .text: 

00000000 <sum>: 
    0: 55      push %ebp 
    1: 89 e5     mov %esp,%ebp 
    3: 8b 45 0c    mov 0xc(%ebp),%eax 
    6: 03 45 08    add 0x8(%ebp),%eax 
    9: 01 05 00 00 00 00  add %eax,0x0 
    f: c9      leave 
    10: c3      ret 
    11: 8d 76 00    lea 0x0(%esi),%esi 

00000014 <main>: 
    14: 55      push %ebp 
    15: 89 e5     mov %esp,%ebp 
    17: 83 ec 08    sub $0x8,%esp 
    1a: 83 e4 f0    and $0xfffffff0,%esp 
    1d: 83 ec 10    sub $0x10,%esp 
    20: 6a 0b     push $0xb 
    22: 6a 0a     push $0xa 
    24: e8 fc ff ff ff   call 25 <main+0x11> 
    29: 31 c0     xor %eax,%eax 
    2b: c9      leave 
    2c: c3      ret 

आदर्श रूप में, सूची:

#include <stdio.h> 
int accum = 0; 

int sum(int x,int y) 
{ 
    int t = x+y; 
    accum +=t; 
    return t; 
} 

int main(int argc,char *argv[]) 
{ 
    int i = 0,x=10,y=11; 
    i = sum(x,y); 
    return 0; 
} 

इसके अलावा, इस कार्यक्रम के ऊपर से उत्पन्न वस्तु कोड है (1) और (2) वही होना चाहिए। लेकिन मुझे दिखाई देता है कि लिस्टिंग में movl, pushl आदि है (1) जबकि mov, उछाल (2) में धक्का। मेरा सवाल है:

  1. वास्तव में प्रोसेसर पर सही असेंबली निर्देश कौन सा निष्पादित किया गया है?
  2. सूची में (1), मैं शुरुआत में इस देखें:

.file "test.c" 
    .globl accum 
     .bss 
     .align 4 
     .type accum, @object 
     .size accum, 4 
    accum: 
     .zero 4 
     .text 
     .p2align 2,,3 
    .globl sum 
     .type sum, @function 

और इस अंत में:

.size main, .-main 
      .section .note.GNU-stack,"",@progbits 
      .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)" 

इसका क्या मतलब है?

धन्यवाद।

उत्तर

13

निर्देश MOV कहा जाता है जो भी संस्करण का उपयोग किया जा रहा है। l प्रत्यय केवल एक जीसीसी/एटी & टी असेंबली सम्मेलन वांछित ऑपरेटरों के आकार को निर्दिष्ट करने के लिए है, इस मामले में 4 बाइट ऑपरेंड।

इंटेल वाक्य रचना में - जहां कोई अस्पष्टता नहीं है - के बजाय अनुदेश यह आकार की आवश्यकता का एक संकेतक के साथ स्मृति पैरामीटर टैग करने के लिए हमेशा की तरह है प्रत्यय लगाना (जैसे BYTE, WORD, DWORD, आदि), यह सिर्फ एक और तरीका है एक ही चीज़ को प्राप्त करने के लिए।

89 55 सही 32-बिट के लिए MOV 32-बिट रजिस्टर EBP से बाइट्स के अनुक्रम रजिस्टर ESP है। लिस्टिंग में कुछ भी गलत नहीं है।


फ़ाइल है कि इस विधानसभा कोड जनरेट किया गया था निर्दिष्ट करता है से:

.file "test.c" 

कहते हैं कि accum एक वैश्विक प्रतीक (बाह्य संबंध के साथ सी चर) है:

.globl accum 

निम्नलिखित बाइट्स bss सेक्शन में रखा जाना चाहिए, यह एक ऐसा अनुभाग है जो ऑब्जेक्ट फ़ाइल में कोई स्थान नहीं लेता है लेकिन इसे रनटाइम पर आवंटित और शून्य किया जाता है।

 .bss 

एक 4 बाइट सीमा पर संरेखित:

 .size accum, 4 
:

 .type accum, @object 

यह चार बाइट्स है:

 .align 4 

यह एक वस्तु (एक चर, नहीं कुछ कोड) है

यहां है जहां accum है परिभाषित, चार शून्य बाइट्स।

accum: 
     .zero 4 

अब पाठ खंड है जो जहां कार्यों को आम तौर पर जमा हो जाती है के लिए bss अनुभाग से स्विच।

 .text 

यकीन है कि हम एक 4 बाइट पर हैं (2^2) सीमा बनाने के लिए गद्दी की तीन बाइट्स को जोड़ें:

 .p2align 2,,3 

sum एक वैश्विक प्रतीक है और यह एक समारोह है।

.globl sum 
     .type sum, @function 

main के आकार "यहाँ" है - "जहां main शुरू कर दिया":

.size main, .-main 

ये जहां जीसीसी विशिष्ट ढेर विकल्प निर्दिष्ट कर रहे हैं। आम तौर पर, यह वह जगह है जहां आप निष्पादन योग्य ढेर (बहुत सुरक्षित नहीं) चुनते हैं या नहीं (आमतौर पर पसंदीदा)।

 .section .note.GNU-stack,"",@progbits 

पहचानें जो इस विधानसभा उत्पन्न संकलक के संस्करण:

 .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)" 
+0

+9,000। धन्यवाद। जीसीसी विशिष्ट स्टैक विकल्पों के बारे में थोड़ा बहुत उपयोगी था। – kevinarpe

0

कोडांतरक लिस्टिंग और disassembler सूची एक ही कोड दिखाने के लिए, लेकिन एक अलग सिंटैक्स का उपयोग करें। संलग्न- एल जीसीसी द्वारा उपयोग किए जाने वाले वाक्यविन्यास संस्करण है। आपके पास टूल्स (सी-कंपाइलर आउटपुट और डिससेबलर) में एक अलग वाक्यविन्यास है जो आपके टूलचेन की कमजोरी दिखाता है।

असमान 11 में ऑफसेट पर असुरक्षित: केवल कुछ कचरा बाइट दिखाता है। अगले फंक्शन मुख्य में प्रवेश बिंदु 4-बाइट गठबंधन है जो इस अंतर को देता है, कचरे से भरें।

.statements का गुच्छा असेंबलर के दस्तावेज़ीकरण द्वारा परिभाषित किया गया है। आमतौर पर वे कोई निष्पादन योग्य कोड नहीं देते हैं।

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