c - कैसे सी लाइन में विधानसभा कोड को सही लाइन को संबद्ध करने के लिए?




debugging assembly (3)

यहां एक उदाहरण है जो एक असेंबली वेबसाइट के माध्यम से मिलती है। यह सी कोड है:

 int main()
 {
     int a = 5;
     int b = a + 6;
     return 0;
 }

यहां संबद्ध असेंबली कोड है:

    (gdb) disassemble
    Dump of assembler code for function main:
    0x0000000100000f50 <main+0>:    push   %rbp
    0x0000000100000f51 <main+1>:    mov    %rsp,%rbp
    0x0000000100000f54 <main+4>:    mov    $0x0,%eax
    0x0000000100000f59 <main+9>:    movl   $0x0,-0x4(%rbp)
    0x0000000100000f60 <main+16>:   movl   $0x5,-0x8(%rbp)
    0x0000000100000f67 <main+23>:   mov    -0x8(%rbp),%ecx
    0x0000000100000f6a <main+26>:   add    $0x6,%ecx
    0x0000000100000f70 <main+32>:   mov    %ecx,-0xc(%rbp)
    0x0000000100000f73 <main+35>:   pop    %rbp
    0x0000000100000f74 <main+36>:   retq   
    End of assembler dump.

मैं सुरक्षित रूप से मान सकता हूँ कि विधानसभा कोड की यह पंक्ति:

  0x0000000100000f6a <main+26>:   add    $0x6,%ecx

सी की इस पंक्ति से संबद्ध:

     int b = a + 6;

लेकिन क्या निकालने का एक तरीका है कि विधानसभा की रेखाएं सी कोड की विशिष्ट पंक्ति से जुड़े हैं?
इस छोटे नमूने में यह बहुत मुश्किल नहीं है, लेकिन बड़े कार्यक्रमों में और जब कोड की एक बड़ी राशि डिबगिंग करते हैं तो यह थोड़ी जटिल हो जाती है


लेकिन क्या निकालने का एक तरीका है कि विधानसभा की रेखाएं सी कोड की विशिष्ट पंक्ति से जुड़े हैं?

हां, सिद्धांत रूप में - आपका कंपाइलर शायद यह कर सकता है (उदाहरण के लिए जीसीसी विकल्प -fverbose-asm ) वैकल्पिक रूप से, objdump -lSd - objdump -lSd या समान एक प्रोग्राम या ऑब्जेक्ट फाइल को स्रोत और रेखा संख्या वाले एनोटेशन के साथ अलग-अलग कर देंगे जहां उपलब्ध।

सामान्य तौर पर, हालांकि, बड़े अनुकूलित प्रोग्राम के लिए, इसका पालन करना बहुत कठिन हो सकता है

यहां तक ​​कि सही एनोटेशन के साथ, आपको अभिव्यक्ति के रूप में एक ही स्रोत पंक्ति को कई बार वर्णित किया जाएगा और बयानों को विभाजित कर दिया जाएगा, इंटरलेव किया गया है और फिर से क्रोड किया गया है, और कई सूत्र अभिव्यक्ति से जुड़े कुछ निर्देश

इस मामले में, आपको अपने स्रोत और विधानसभा के बीच संबंधों के बारे में सोचने की जरूरत है, लेकिन इसमें कुछ प्रयास किए गए हैं


@ बेकार बहुत सही है वैसे भी, पता करने के लिए कि सी मशीन कोड में आ गया है, उसमें मार्करों को इंजेक्ट करना है; उदाहरण के लिए,

#define ASM_MARK do { asm __volatile__("nop; nop; nop;\n\t" :::); } while (0);

int main()
{
    int a = 5;
    ASM_MARK;
       int b = a + 6;
    ASM_MARK;
    return 0;
}

तुम देखोगे:

main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $5, -4(%rbp)
        nop; nop; nop;

        movl    -4(%rbp), %eax
        addl    $6, %eax
        movl    %eax, -8(%rbp)
        nop; nop; nop;

        movl    $0, %eax
        popq    %rbp
        ret

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


सबसे पहले, आपको कार्यक्रम के अंदर स्रोत वस्तु के बारे में अपने ऑब्जेक्ट फ़ाइल की जानकारी रखने के लिए कंपाइल करने की जरूरत है, या तो gdwarf या g flag या दोनों के द्वारा। इसके बाद, यदि आप डीबग करना चाहते हैं, तो अनुकूलन से बचने के लिए कंपाइलर महत्वपूर्ण है, अन्यथा यह पत्राचार कोड <> विधानसभा देखना मुश्किल है

gcc -gdwarf -g3 -O0 prog.c -o out

इसके बाद, डिस्साम्बलर को स्रोत कोड आउटपुट करने के लिए बताएं। source ध्वज में disassemble ध्वज शामिल है

objdump --source out