2012-09-03 13 views
6

से कॉलिंग सम्मेलन प्राप्त करना मैं डीडब्ल्यूएआरएफ जानकारी से सम्मेलनों को कॉल करने के बारे में जानकारी प्राप्त करने की कोशिश कर रहा हूं। अधिक विशिष्ट, मैं यह जानना चाहता हूं कि कार्यों के लिए तर्क पारित करने के लिए कौन से रजिस्टरों/स्टैक स्थानों का उपयोग किया जाता है। मेरी समस्या यह है कि मुझे कुछ मामलों में डीडब्ल्यूएआरएफ डंप से कुछ गलत जानकारी मिल रही है।डीडब्ल्यूएआरएफ जानकारी

gcc -c -g -m32 test.c -o test.o 

अब जब मैं निम्न आदेश का उपयोग बौना डंप पाने के लिए:

int __attribute__ ((fastcall)) __attribute__ ((noinline)) mult (int x, int y) { 
return x*y; 
} 

मैं निम्न आदेश का उपयोग कर इस उदाहरण संकलन: उदाहरण मैं उपयोग कर रहा हूँ निम्नलिखित "सी कोड" है

< 2><0x00000042>  DW_TAG_formal_parameter 
         DW_AT_name     "x" 
         DW_AT_decl_file    0x00000001 /home/khaled/Repo_current/trunk/test.c 
         DW_AT_decl_line    0x00000001 
         DW_AT_type     <0x0000005b> 
         DW_AT_location    DW_OP_fbreg -12 
< 2><0x0000004e>  DW_TAG_formal_parameter 
         DW_AT_name     "y" 
         DW_AT_decl_file    0x00000001 /home/khaled/Repo_current/trunk/test.c 
         DW_AT_decl_line    0x00000001 
         DW_AT_type     <0x0000005b> 
         DW_AT_location    DW_OP_fbreg -16 
0123:
dwarfdump test.o 

मैं इस समारोह के बारे में निम्नलिखित जानकारी हो रही है

DW_AT_ स्थान प्रविष्टियों को देखते हुए, यह फ्रेम आधार से कुछ ऑफसेट है। इसका तात्पर्य है कि वे स्मृति तर्क हैं, लेकिन वास्तविक कॉलिंग सम्मेलन "फास्टकॉल" उन्हें रजिस्टरों में पास करने के लिए मजबूर करता है। उत्पादित ऑब्जेक्ट फ़ाइल के डिस्सेप्लर को देखकर, मैं देख सकता हूं कि फ़ंक्शन के प्रवेश बिंदु पर स्थानों को स्टैक करने के लिए उन्हें रजिस्टरों से कॉपी किया गया है। बौने डंप से किसी अन्य तरीके से जानने का कोई तरीका है - जहां शुरुआत में कॉल पर तर्क पारित किए जाते हैं?

धन्यवाद,

उत्तर

6

क्योंकि आप gcc -c -g -m32 test.c -o test.o उपयोग कर रहे हैं। हालांकि यह fastcall फ़ंक्शन है, GCC अभी भी फ़ंक्शन की शुरुआत में रजिस्टरों से स्टैक फ्रेम में मूल्यों को सहेजने के लिए कोड उत्पन्न करने की आवश्यकता है। इसके बिना, कोई डीबगर या gdb प्रोग्राम डीबग नहीं कर सकता है या वे कहेंगे कि तर्क अनुकूलित किया जा रहा है और दिखाया नहीं गया है। यह असंभव डीबगिंग बनाता है।

x86_64 में, कंपाइलर कुछ रजिस्ट्रारों का उपयोग डिफ़ॉल्ट रूप से कुछ तर्कों को पास करने के लिए करता है, यहां तक ​​कि किसी फ़ंक्शन के लिए विशेषता fastcall निर्दिष्ट किए बिना। आप यह भी पा सकते हैं कि उन रजिस्टरों को ढेर में भी कॉपी किया जा रहा है।

// x86_64 assembly code 
_mult: 
Leh_func_begin1: 
     pushq %rbp 
Ltmp0: 
     movq %rsp, %rbp 
Ltmp1: 
     movl %edi, -4(%rbp) 
     movl %esi, -8(%rbp) 
     movl -4(%rbp), %eax 
     movl -8(%rbp), %ecx 
     imull %ecx, %eax 

यदि आप अनुकूलन झंडा -O, -O2, -O3 (कोई बात नहीं -g या नहीं) चालू करने पर आप एकत्रित न और कुछ भी नहीं स्टैक फ्रेम पर कॉपी बनाने के है पा सकते हैं। और जब आप अनुकूलित निष्पादन योग्य फ़ाइल को gdb करते हैं, और स्थानीय चर दिखाने के लिए फ़ंक्शन की शुरुआत में रोकते हैं, तो gdb आपको बताएगा कि उन तर्कों को अनुकूलित किया जा रहा है।

32-बिट कार्यक्रम के dwarfdump उदाहरण की तरह

0x00000083:  TAG_formal_parameter [4] 
       AT_name("x") 
       AT_decl_file("test.c") 
       AT_decl_line(1) 
       AT_type({0x0000005f} (int)) 
       AT_location(0x00000000 
        0x00000000 - 0x00000003: ecx 
        0x00000003 - 0x00000018: ecx) 

0x00000090:  TAG_formal_parameter [4] 
       AT_name("y") 
       AT_decl_file("test.c") 
       AT_decl_line(1) 
       AT_type({0x0000005f} (int)) 
       AT_location(0x0000001e 
        0x00000000 - 0x00000003: edx 
        0x00000003 - 0x00000018: edx) 

लगेगा और आप उत्पन्न विधानसभा कोड बहुत सरल और साफ है पा सकते हैं।

_mult: 
     pushl %ebp 
     movl %esp, %ebp 
     movl %ecx, %eax 
     imull %edx, %eax 
     popl %ebp 
     ret  $12 
संबंधित मुद्दे