पठनीय विधानसभा का निर्माण करने के लिए GCC का उपयोग करना?


256

मैं सोच रहा था कि मशीन कोड के mnemonic संस्करण को डंप करने के लिए मेरी C स्रोत फ़ाइल पर GCC का उपयोग कैसे किया जाए ताकि मैं देख सकूं कि मेरा कोड क्या संकलित किया जा रहा है। आप यह जावा के साथ कर सकते हैं लेकिन मैं जीसीसी के साथ एक तरीका नहीं खोज सका हूं।

मैं विधानसभा में एक सी विधि को फिर से लिखने की कोशिश कर रहा हूं और यह देख रहा हूं कि जीसीसी एक बड़ी मदद कैसे करेगा।


25
ध्यान दें कि 'बायटेकोड' का अर्थ आमतौर पर वीएम द्वारा उपभोग किया जाने वाला कोड होता है, जैसे जेवीएम या .NET का सीएलआर। GCC के आउटपुट को 'मशीन कोड', 'मशीन लैंग्वेज', या 'असेंबली लैंग्वेज' कहा जाता है
जेवियर

2
मैंने गॉडबोल्ट का उपयोग करते हुए एक उत्तर जोड़ा क्योंकि यह तेजी से प्रयोग करने के लिए एक बहुत शक्तिशाली उपकरण है कि विभिन्न विकल्प आपके कोड पीढ़ी को कैसे प्रभावित करते हैं।
शफीक यघमौर



एसएसएम आउटपुट को मानव पठनीय बनाने के बारे में अधिक सुझावों के लिए, यह भी देखें: जीसीसी / क्लैंग असेंबली आउटपुट से "शोर" कैसे निकालें?
पीटर कॉर्ड्स

जवाबों:


335

यदि आप डिबग प्रतीकों के साथ संकलित करते हैं, तो आप objdumpअधिक पठनीय डिस्सैस बनाने के लिए उपयोग कर सकते हैं ।

>objdump --help
[...]
-S, --source             Intermix source code with disassembly
-l, --line-numbers       Include line numbers and filenames in output

objdump -drwC -Mintel अच्छा है:

  • -rरिलोकेशन पर प्रतीक नाम दिखाता है (इसलिए आप नीचे दिए गए निर्देश putsमें देखेंगे call)
  • -R डायनामिक-लिंकिंग रिलोकेशन / प्रतीक नाम दिखाता है (साझा पुस्तकालयों पर उपयोगी)
  • -C सी + + प्रतीक नाम demangles
  • -w "वाइड" मोड है: यह मशीन-कोड बाइट्स को लाइन-रैप नहीं करता है
  • -Mintel: .intel_syntax noprefixAT & T के बजाय GAS / Binutils MASM- जैसे सिंटैक्स का उपयोग करें
  • -S: disassembly के साथ इंटरलेवेव सोर्स लाइन्स।

आप alias disas="objdump -drwCS -Mintel"अपने अंदर कुछ डाल सकते हैं~/.bashrc


उदाहरण:

> gcc -g -c test.c
> objdump -d -M intel -S test.o

test.o:     file format elf32-i386


Disassembly of section .text:

00000000 <main>:
#include <stdio.h>

int main(void)
{
   0:   55                      push   ebp
   1:   89 e5                   mov    ebp,esp
   3:   83 e4 f0                and    esp,0xfffffff0
   6:   83 ec 10                sub    esp,0x10
    puts("test");
   9:   c7 04 24 00 00 00 00    mov    DWORD PTR [esp],0x0
  10:   e8 fc ff ff ff          call   11 <main+0x11>

    return 0;
  15:   b8 00 00 00 00          mov    eax,0x0
}
  1a:   c9                      leave  
  1b:   c3                      ret

3
क्या केवल इंटेल निर्देशों को हथियाने के लिए स्विच है?
जेम्स

3
इंटेल प्रोसेसर पर चलने के बाद से ये सभी इंटेल के निर्देश हैं: डी।
टोटो

12
@toto मुझे लगता है कि वह इसका मतलब है इंटेल एटी एंड टी वाक्य रचना के बजाय वाक्यविन्यास
आपे से बाहर

7
स्विच अनुक्रम का उपयोग करके मध्यवर्ती ऑब्जेक्ट फ़ाइल को छोड़ना संभव है -Wa,-adhln -g to gcc। यह मानता है कि कोडांतरक गैस है और यह हमेशा ऐसा नहीं हो सकता है।
मार्क बटलर

8
@ जेम्स हां, आपूर्ति -Mintel
फज

106

यदि आप जीसीसी को झंडा देते हैं -fverbose-asm, तो यह होगा

इसे और अधिक पठनीय बनाने के लिए उत्पन्न असेंबली कोड में अतिरिक्त कमेंटरी जानकारी रखें।

[...] जोड़ा टिप्पणियों में शामिल हैं:

  • संकलक संस्करण और कमांड लाइन विकल्पों पर जानकारी,
  • स्रोत कोड लाइनों को विधानसभा निर्देशों के साथ, फॉर्म में नाम से जोड़ा गया: LINENUMBER: CONTENT OF LINE,
  • संकेत, जिस पर उच्च-स्तरीय अभिव्यक्तियाँ विभिन्न असेंबली इंस्ट्रक्शन ऑपरेंड्स के अनुरूप हैं।

लेकिन फिर भी, मैं सभी के लिए इस्तेमाल किया स्विच खो दिया होगा objdump- objdump -drwCS -Mintelहै, तो मैं कैसे की तरह कुछ का उपयोग कर सकते verboseके साथ objdump? ताकि मैं asm कोड में टिप्पणी कर सकूं, जैसा कि -fverbose-asmgcc में है?
हरदंस

1
@ हर्ड्समैन: आप नहीं कर सकते। अतिरिक्त सामान -fverbose-asmजोड़ता है आउटपुट के asm सिंटैक्स में टिप्पणियों के रूप में, न कि निर्देश जो .oफ़ाइल में कुछ भी अतिरिक्त डाल देगा । यह सब इकट्ठा समय पर छोड़ दिया गया है। Disassembly के बजाय कंपाइलर एएसएम आउटपुट को देखें, जैसे कि गॉडबोल्ट.ओआरजी पर जहां आप इसे आसानी से माउसओवर के माध्यम से सोर्स लाइन और संबंधित स्रोत / एसएम लाइनों के रंग हाइलाइटिंग के माध्यम से मैच कर सकते हैं। जीसीसी / क्लैंग असेंबली आउटपुट से "शोर" कैसे निकालें?
पीटर कॉर्डेस

75

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

gcc -O2 -S foo.c

फ़ाइल foo.s. पर जनरेट किए गए असेंबली कोड को छोड़ देगा

Http://www.delorie.com/djgpp/v2faq/faq8_20.html से सीधे रिप्ड (लेकिन त्रुटिपूर्ण हटा -c)


35
आपको -c और -S को मिक्स नहीं करना चाहिए, केवल उनमें से एक का उपयोग करें। इस मामले में, एक दूसरे को पछाड़ रहा है, शायद उस क्रम पर निर्भर करता है जिसमें वे उपयोग किए जाते हैं।
एडम रोसेनफील्ड

4
@AdamRosenfield 'मिक्स -c और -S' नहीं होना चाहिए? यदि यह सच है, तो हमें लेखक को याद दिलाना चाहिए और उसे संपादित करना चाहिए।
टोनी

5
@Tony: gcc.gnu.org/oniltocs/gcc/Overall-Options.html#Overall-Options "आप उपयोग कर सकते हैं ... विकल्पों में से एक -c, -S, या -E यह कहना है कि जहां gcc को रोकना है। "
नैट एल्ड्रेडगे

1
यदि आप सभी मध्यवर्ती आउटपुट चाहते हैं, तो उपयोग करें gcc -march=native -O3 -save-temps। आप अभी भी -cऑब्जेक्ट-फ़ाइल निर्माण को लिंक करने की कोशिश किए बिना, या जो कुछ भी हो, उसे रोकने के लिए उपयोग कर सकते हैं ।
पीटर कॉर्डेस

2
-save-tempsदिलचस्प है क्योंकि यह एक में डंप करता है, सटीक कोड जनरेट कोड जाता है, जबकि कंपाइलर को कॉल करने का दूसरा विकल्प -Sदो बार संकलित करने का मतलब है, और संभवतः विभिन्न विकल्पों के साथ। लेकिन -save-temps सभी मौजूदा निर्देशिका में डंप है, जो गड़बड़ है। ऐसा लगता है कि यह आपके कोड का निरीक्षण करने के लिए एक उपकरण के बजाय जीसीसी के लिए डिबग विकल्प के रूप में अधिक इरादा है।
स्टीफन गौरिचोन

50

-SX86 आधारित सिस्टम पर GCC में स्विच का उपयोग डिफ़ॉल्ट रूप से एटी एंड टी सिंटैक्स का एक डंप पैदा करता है, जिसे -masm=attस्विच के साथ निर्दिष्ट किया जा सकता है , जैसे:

gcc -S -masm=att code.c

यदि आप इंटेल सिंटैक्स में डंप का उत्पादन करना चाहते हैं, तो आप -masm=intelस्विच का उपयोग कर सकते हैं , जैसे:

gcc -S -masm=intel code.c

(दोनों code.cफ़ाइल में अपने विभिन्न सिंटैक्स के डंप का उत्पादन करते हैंcode.s क्रमशः हैं)

Objdump के साथ समान प्रभाव उत्पन्न करने के लिए, आप --disassembler-options= intel/ attस्विच का उपयोग करना चाहेंगे , एक उदाहरण (वाक्यविन्यास में अंतर को दर्शाने के लिए कोड डंप के साथ):

 $ objdump -d --disassembler-options=att code.c
 080483c4 <main>:
 80483c4:   8d 4c 24 04             lea    0x4(%esp),%ecx
 80483c8:   83 e4 f0                and    $0xfffffff0,%esp
 80483cb:   ff 71 fc                pushl  -0x4(%ecx)
 80483ce:   55                      push   %ebp
 80483cf:   89 e5                   mov    %esp,%ebp
 80483d1:   51                      push   %ecx
 80483d2:   83 ec 04                sub    $0x4,%esp
 80483d5:   c7 04 24 b0 84 04 08    movl   $0x80484b0,(%esp)
 80483dc:   e8 13 ff ff ff          call   80482f4 <puts@plt>
 80483e1:   b8 00 00 00 00          mov    $0x0,%eax
 80483e6:   83 c4 04                add    $0x4,%esp 
 80483e9:   59                      pop    %ecx
 80483ea:   5d                      pop    %ebp
 80483eb:   8d 61 fc                lea    -0x4(%ecx),%esp
 80483ee:   c3                      ret
 80483ef:   90                      nop

तथा

$ objdump -d --disassembler-options=intel code.c
 080483c4 <main>:
 80483c4:   8d 4c 24 04             lea    ecx,[esp+0x4]
 80483c8:   83 e4 f0                and    esp,0xfffffff0
 80483cb:   ff 71 fc                push   DWORD PTR [ecx-0x4]
 80483ce:   55                      push   ebp
 80483cf:   89 e5                   mov    ebp,esp
 80483d1:   51                      push   ecx
 80483d2:   83 ec 04                sub    esp,0x4
 80483d5:   c7 04 24 b0 84 04 08    mov    DWORD PTR [esp],0x80484b0
 80483dc:   e8 13 ff ff ff          call   80482f4 <puts@plt>
 80483e1:   b8 00 00 00 00          mov    eax,0x0
 80483e6:   83 c4 04                add    esp,0x4
 80483e9:   59                      pop    ecx
 80483ea:   5d                      pop    ebp
 80483eb:   8d 61 fc                lea    esp,[ecx-0x4]
 80483ee:   c3                      ret    
 80483ef:   90                      nop

क्या ... gcc -S -masm=intel test.cमेरे लिए बिल्कुल काम नहीं किया, मैं इंटेल और एटी एंड टी सिंटैक्स के कुछ crossbreed इस तरह से मिला: इस के mov %rax, QWORD PTR -24[%rbp]बजाय movq -24(%rbp), %rax:।
L --o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e

1
अच्छी टिप। यह ध्यान दिया जाना चाहिए कि यह भी काम करता है जब .oऔर ASM फ़ाइलों के समानांतर आउटपुट प्रदर्शन करते हैं , अर्थात-Wa,-ahls -o yourfile.o yourfile.cpp>yourfile.asm
अंडरस्कोर_ड

इस्तेमाल कर सकते हैं -Mविकल्प है, यह रूप में एक ही है --disassembler-optionsजैसे, लेकिन बहुत कम,objdump -d -M intel a.out | less -N
एरिक वांग

34

Godbolt एक बहुत ही उपयोगी उपकरण है, उनकी सूची में केवल C ++ कंपाइलर हैं, लेकिन आप -x cकोड का इलाज करने के लिए ध्वज का उपयोग कर सकते हैं क्योंकि यह C. कोड के रूप में होगा और फिर आपके कोड साइड के लिए असेंबली लिस्टिंग जनरेट करेगा और आप Colouriseजनरेट करने के विकल्प का उपयोग कर सकते हैं रंगीन बार नेत्रहीन संकेत देते हैं कि कौन सा स्रोत कोड उत्पन्न विधानसभा में मैप करता है। उदाहरण के लिए निम्नलिखित कोड:

#include <stdio.h>

void func()
{
  printf( "hello world\n" ) ;
}

निम्नलिखित कमांड लाइन का उपयोग कर:

-x c -std=c99 -O3

और Colouriseनिम्नलिखित उत्पन्न करेगा:

यहां छवि विवरण दर्ज करें


यह जानना अच्छा होगा कि गॉडबोल्ट फिल्टर कैसे काम करते हैं: .LC0, .text, // और इंटेल। इंटेल आसान है -masm=intelलेकिन बाकी के बारे में क्या?
जेड बॉसन

मुझे लगता है कि यह यहाँ समझाया गया है stackoverflow.com/a/38552509/2542702
Z boson

Godbolt C का समर्थन करते हैं (रुस्ट, डी, पास्कल ... जैसी अन्य भाषाओं के एक टन के साथ)। यह सिर्फ इतना है कि बहुत कम सी कंपाइलर हैं, इसलिए सी ++ कंपाइलर का उपयोग करना अभी भी बेहतर है-x c
phuclv

23

क्या आपने कोशिश की gcc -S -fverbose-asm -O source.cतो उत्पन्न में देखोsource.s कोडांतरक फ़ाइल को देखें?

उत्पन्न कोडर कोड में चला जाता है source.s(आप -o कोडांतरक-फ़ाइलनाम के साथ इसे ओवरराइड कर सकते हैं ); -fverbose-asmविकल्प संकलक कुछ कोडांतरक टिप्पणी "समझा" उत्पन्न कोडांतरक कोड फेंकना लिए कहता है। -Oविकल्प एक सा अनुकूलन करने के लिए संकलक पूछता है (इसके साथ और अधिक का अनुकूलन कर सकता है -O2या-O3 )।

यदि आप यह समझना चाहते हैं कि क्या gccकरने की कोशिश की जा रही है, -fdump-tree-allलेकिन सतर्क रहें: आपको सैकड़ों डंप फाइलें मिलेंगी।

BTW, GCC एक्स्टेंसिबल थ्रू प्लगइन्स है या MELT (GCC को बढ़ाने के लिए एक उच्च स्तरीय डोमेन विशिष्ट भाषा है, जिसे मैंने 2017 में छोड़ दिया था)


शायद उल्लेख है कि उत्पादन में होगा source.s, क्योंकि बहुत से लोग कंसोल पर एक प्रिंटआउट की उम्मीद करेंगे।
रुबेनलागुना

1
@ecerulm: स्टंपआउट के -S -o-लिए डंप। -masm=intelयदि आप NASM / YASM सिंटैक्स का उपयोग करना चाहते हैं तो यह सहायक है। (लेकिन यह qword ptr [mem]सिर्फ के बजाय का उपयोग करता है , qwordतो यह NASM / YASM की तुलना में Intel / MASM की तरह अधिक है)। gcc
पीटर कॉर्डेस

2
उल्लेख करना भूल गए: यदि आप "स्रोत के समान लेकिन हर स्रोत लाइन के बाद स्टोर / रीलोड के शोर के बिना" देख रहे हैं, तो -Ogइससे भी बेहतर है -O1। इसका अर्थ है "डिबगिंग के लिए ऑप्टिमाइज़ करना" और बिना किसी बहुत मुश्किल / कठिन-अनुवर्ती अनुकूलन के एएसएम बना देता है जो स्रोत को सब कुछ कहता है। यह gcc4.8 के बाद से उपलब्ध है, लेकिन क्लैंग 3.7 अभी भी इसके पास नहीं है। IDK अगर उन्होंने इसके खिलाफ या क्या फैसला किया।
पीटर कॉर्डेस

19

आप इसके लिए gdb का उपयोग objdump की तरह कर सकते हैं।

यह उद्धरण http://sources.redhat.com/gdb/current/onbuildocs/gdb_9.html#SEC64 से लिया गया है


यहाँ एक उदाहरण इंटेल x86 के लिए मिश्रित स्रोत + असेंबली दिखा रहा है:

  (gdb) disas / m main
फ़ंक्शन मुख्य के लिए कोडांतरक कोड का डंप:
5 {
0x08048330:% ebp को पुश करें
0x08048331: mov% esp,% ebp
0x08048333: उप $ 0x8,% esp
0x08048336: और $ 0xfffffff0,% esp
0x08048339: उप $ 0x10,% esp

6 प्रिंटफ ("हैलो। \ n");
0x0804833c: movl $ 0x8048440, (% esp)
0x08048343: 0x8048284 पर कॉल करें 

7 वापसी 0;
8}
0x08048348: mov $ 0x0,% eax
0x0804834d: छुट्टी
0x0804834e: सेवानिवृत्त

कोडांतरक डंप का अंत।


और GDB के disassembler को Intel सिंटैक्स में बदलने के लिए, set disassembly-flavor intelकमांड का उपयोग करें ।
रुस्लान

13

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

gcc -O2 -S -c foo.c


4

मैंने gcc को एक शॉट नहीं दिया है, लेकिन g ++ के मामले में। नीचे दिया गया कमांड मेरे लिए काम करता है। डिबग बिल्ड और -वा के लिए -g, -adhln को सोर्स कोड के साथ लिस्टिंग के लिए कोडांतरक को पास किया जाता है

g ++ -g -Wa, -adhln src.cpp


यह gcc के लिए भी काम करता है! -वा, ... असेंबलर भाग के लिए कमांड लाइन विकल्पों के लिए है (सी / ++ संकलन के बाद जीसीसी / जी ++ में निष्पादित करें)। यह आंतरिक रूप से (as.exe विंडोज में) के रूप में आमंत्रित करता है। अधिक सहायता देखने के लिए कमांड लाइन के रूप में देखें - के रूप में
हार्टमट शॉरिग

0

उपयोग -वा, -DHL विकल्प पर उत्पादन करने के लिए gcc या g ++ पर विकल्प के रूप में स्टडआउट के लिए।

-वा, ... असेंबलर भाग के लिए कमांड लाइन विकल्पों के लिए है (सी / ++ संकलन के बाद जीसीसी / जी ++ में निष्पादित करें)। के रूप में यह आह्वान करता है आंतरिक (as.exe विंडोज में) के । देख

> as-help

कमांड लाइन के रूप में gcc के अंदर कोडांतरक उपकरण के लिए और अधिक मदद देखने के लिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.