जवाबों:
-S
Gcc (या g ++) के विकल्प का उपयोग करें ।
gcc -S helloworld.c
यह helloworld.c पर प्रीप्रोसेसर (सीपीपी) चलाएगा, प्रारंभिक संकलन का प्रदर्शन करेगा और फिर कोडांतरक चलाने से पहले रोक देगा।
डिफ़ॉल्ट रूप से यह एक फ़ाइल आउटपुट करेगा helloworld.s
। आउटपुट फ़ाइल को -o
विकल्प का उपयोग करके अभी भी सेट किया जा सकता है।
gcc -S -o my_asm_output.s helloworld.c
बेशक यह केवल तभी काम करता है जब आपके पास मूल स्रोत हो। एक विकल्प यदि आपके पास केवल परिणामी ऑब्जेक्ट फ़ाइल है objdump
, --disassemble
विकल्प सेट करके (या -d
संक्षिप्त रूप के लिए)।
objdump -S --disassemble helloworld > helloworld.dump
यह विकल्प सबसे अच्छा काम करता है यदि डिबगिंग विकल्प ऑब्जेक्ट फ़ाइल ( -g
संकलन समय पर) के लिए सक्षम है और फ़ाइल को छीन नहीं लिया गया है।
रनिंग file helloworld
आपको विस्तार के स्तर तक कुछ संकेत देगा जो आपको objdump का उपयोग करके मिलेगा।
.intel_syntax
है नहीं एनएएसएम के साथ संगत । यह MASM की तरह अधिक है (जैसे mov eax, symbol
एक भार है, NASM के विपरीत जहां यह mov r32, imm32
पते का है), लेकिन MASM के साथ पूरी तरह से संगत नहीं है। मैं इसे पढ़ने के लिए एक अच्छे प्रारूप के रूप में अत्यधिक अनुशंसा करता हूं, खासकर यदि आप NASM सिंटैक्स में लिखना पसंद करते हैं। objdump -drwC -Mintel | less
या gcc foo.c -O1 -fverbose-asm -masm=intel -S -o- | less
उपयोगी हैं। (यह भी देखें कि जीसीसी / क्लैंग असेंबली आउटपुट से "शोर" कैसे निकालना है? )। -masm=intel
क्लैंग के साथ भी काम करता है।
gcc -O -fverbose-asm -S
यह सी कोड + लाइन नंबरों के साथ असेंबली कोड उत्पन्न करेगा, अधिक आसानी से यह देखने के लिए कि कौन सी लाइनें किस कोड को उत्पन्न करती हैं:
# create assembler code:
g++ -S -fverbose-asm -g -O2 test.cc -o test.s
# create asm interlaced with source lines:
as -alhnd test.s > test.lst
प्रोग्रामर के लिए एल्गोरिदम में मिला , पेज 3 (जो पीडीएफ का कुल 15 वां पेज है)।
as
OS X पर ये झंडे नहीं हैं। यदि यह किया गया था, हालांकि, आप -Wa
विकल्पों को पास करने के लिए इसका उपयोग करके शायद एक-लाइन कर सकते हैं as
।
g++ -g -O0 -c -fverbose-asm -Wa,-adhln test.cpp > test.lst
इसका छोटा संस्करण होगा।
gcc -c -g -Wa,-ahl=test.s test.c
या तो इस्तेमाल कर सकते हैं याgcc -c -g -Wa,-a,-ad test.c > test.txt
-O0
? यह उन भारों / भंडारों से भरा है जो किसी मूल्य को ट्रैक करना कठिन बनाते हैं, और अनुकूलित कोड कितना कुशल होगा, इसके बारे में आपको कुछ नहीं बताता है।
निम्नलिखित कमांड लाइन क्रिश्चियन गार्बिन के ब्लॉग से है
g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt
मैं विन + एक्सपी पर एक डॉस विंडो से जी ++ भागा, एक रूटीन के खिलाफ जिसमें एक निहित कास्ट है
c:\gpp_code>g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt
horton_ex2_05.cpp: In function `int main()':
horton_ex2_05.cpp:92: warning: assignment to `int' from `double'
आउटपुट को मूल C ++ कोड के साथ उत्पन्न कोड इटसेरस्पेंड किया गया है (C ++ कोड उत्पन्न asm स्ट्रीम में टिप्पणियों के रूप में दिखाया गया है)
16:horton_ex2_05.cpp **** using std::setw;
17:horton_ex2_05.cpp ****
18:horton_ex2_05.cpp **** void disp_Time_Line (void);
19:horton_ex2_05.cpp ****
20:horton_ex2_05.cpp **** int main(void)
21:horton_ex2_05.cpp **** {
164 %ebp
165 subl $128,%esp
?GAS LISTING C:\DOCUME~1\CRAIGM~1\LOCALS~1\Temp\ccx52rCc.s
166 0128 55 call ___main
167 0129 89E5 .stabn 68,0,21,LM2-_main
168 012b 81EC8000 LM2:
168 0000
169 0131 E8000000 LBB2:
169 00
170 .stabn 68,0,25,LM3-_main
171 LM3:
172 movl $0,-16(%ebp)
-O2
, या जो भी अनुकूलन विकल्प आप वास्तव में अपने प्रोजेक्ट का निर्माण करते समय उपयोग करते हैं, यदि आप यह देखना चाहते हैं कि कैसे gcc आपके कोड का अनुकूलन करता है। (या यदि आप एलटीओ का उपयोग करते हैं, जैसे आपको करना चाहिए, तो आपको लिंकर आउटपुट को अलग करना होगा ताकि आप वास्तव में प्राप्त कर सकें।)
यदि आप जो देखना चाहते हैं, वह आउटपुट के लिंकिंग पर निर्भर करता है, तो आउटपुट ऑब्जेक्ट फ़ाइल / निष्पादन योग्य पर objdump उपरोक्त gcc -S के अतिरिक्त भी उपयोगी हो सकता है। यहाँ लोरेन मेरिट द्वारा एक बहुत ही उपयोगी स्क्रिप्ट है जो डिफ़ॉल्ट ओब्जेक्टम्प सिंटैक्स को अधिक पठनीय नस्म सिंटैक्स में परिवर्तित करती है:
#!/usr/bin/perl -w
$ptr='(BYTE|WORD|DWORD|QWORD|XMMWORD) PTR ';
$reg='(?:[er]?(?:[abcd]x|[sd]i|[sb]p)|[abcd][hl]|r1?[0-589][dwb]?|mm[0-7]|xmm1?[0-9])';
open FH, '-|', '/usr/bin/objdump', '-w', '-M', 'intel', @ARGV or die;
$prev = "";
while(<FH>){
if(/$ptr/o) {
s/$ptr(\[[^\[\]]+\],$reg)/$2/o or
s/($reg,)$ptr(\[[^\[\]]+\])/$1$3/o or
s/$ptr/lc $1/oe;
}
if($prev =~ /\t(repz )?ret / and
$_ =~ /\tnop |\txchg *ax,ax$/) {
# drop this line
} else {
print $prev;
$prev = $_;
}
}
print $prev;
close FH;
मुझे संदेह है कि यह gcc -S के आउटपुट पर भी इस्तेमाल किया जा सकता है।
mov eax,ds:0x804b794
बहुत NASMish नहीं है। इसके अलावा, कभी-कभी यह केवल उपयोगी जानकारी को स्ट्रिप करता है: movzx eax,[edx+0x1]
पाठक को यह अनुमान लगाने के लिए छोड़ देता है कि मेमोरी ऑपरेंड था byte
या नहीं word
।
objconv
उपयोग करें । आप इसे आउटपुट फ़ाइल = के साथ स्टडआउट करने के लिए इकट्ठा /dev/stdout
कर सकते हैं, ताकि आप less
देखने के लिए पाइप कर सकें । वहाँ भी है ndisasm
, लेकिन यह केवल फ्लैट बायनेरिज़ को अलग करता है, और ऑब्जेक्ट फ़ाइलों (ELF / PE) के बारे में नहीं जानता है।
जैसा कि सभी ने बताया है, -S
GCC के विकल्प का उपयोग करें । मैं यह भी जोड़ना चाहूंगा कि परिणाम भिन्न हो सकते हैं (बेतहाशा!) इस आधार पर कि आप अनुकूलन विकल्प जोड़ते हैं या नहीं ( -O0
किसी के लिए भी, नहीं)-O2
एग्रेसिव ऑप्टिमाइज़ेशन के लिए)।
विशेष रूप से RISC आर्किटेक्चर पर, कंपाइलर अक्सर अनुकूलन करने में मान्यता से परे कोड को बदल देगा। परिणामों को देखने के लिए यह प्रभावशाली और आकर्षक है!
जैसा कि पहले उल्लेख किया गया है, -S ध्वज को देखें।
यह झंडे के '-दंप-ट्री' परिवार को देखने के लायक है, विशेष रूप से '-fdump-tree-all', जो आपको gcc के कुछ मध्यवर्ती रूप देखने देता है। ये अक्सर कोडांतरक (कम से कम मेरे लिए) से अधिक पठनीय हो सकते हैं, और आपको देखते हैं कि अनुकूलन कैसे प्रदर्शन करता है।
मुझे उत्तर के बीच यह संभावना दिखाई नहीं दे रही है, शायद इसलिए कि सवाल 2008 का है, लेकिन 2018 में आप मैट गोल्डबोल्ट की ऑनलाइन वेबसाइट का उपयोग कर सकते हैं https://godbolt.org
आप स्थानीय रूप से भी क्लोन क्लोन कर सकते हैं और अपनी परियोजना https://github.com/mattgodbolt/compiler-explorer चला सकते हैं
-save-temps
इसका उल्लेख https://stackoverflow.com/a/17083009/895245 पर किया गया था लेकिन मैं इसे और उदाहरण देता हूँ।
इस विकल्प का बड़ा लाभ खत्म हो गया -S
है कि किसी भी बिल्ड स्क्रिप्ट में इसे जोड़ना बहुत आसान है, बिना बिल्ड में ज्यादा दखल दिए।
जब तुम करोगे:
gcc -save-temps -c -o main.o main.c
main.c
#define INC 1
int myfunc(int i) {
return i + INC;
}
और अब, सामान्य आउटपुट के अलावा main.o
, वर्तमान कार्यशील निर्देशिका में निम्न फाइलें भी हैं:
main.i
एक बोनस है और इसमें पूर्वनिर्मित फ़ाइल शामिल है:
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"
int myfunc(int i) {
return i + 1;
}
main.s
इसमें वांछित जनरेट विधानसभा शामिल है:
.file "main.c"
.text
.globl myfunc
.type myfunc, @function
myfunc:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
addl $1, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size myfunc, .-myfunc
.ident "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0"
.section .note.GNU-stack,"",@progbits
यदि आप इसे बड़ी संख्या में फ़ाइलों के लिए करना चाहते हैं, तो इसके बजाय उपयोग करने पर विचार करें:
-save-temps=obj
जो मध्यवर्ती फ़ाइलों को -o
वर्तमान कार्य निर्देशिका के बजाय ऑब्जेक्ट आउटपुट के समान निर्देशिका में सहेजता है , इस प्रकार संभावित बेसनेम टकराव से बचा जाता है।
इस विकल्प के बारे में एक और अच्छी बात यह है कि यदि आप जोड़ते हैं -v
:
gcc -save-temps -c -o main.o -v main.c
यह वास्तव में बदसूरत अस्थायी के बजाय उपयोग की जा रही स्पष्ट फाइलों को दिखाता है /tmp
, इसलिए यह जानना आसान है कि क्या चल रहा है, जिसमें प्रीप्रोसेसिंग / संकलन / असेंबली चरण शामिल हैं:
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu main.c -mtune=generic -march=x86-64 -fpch-preprocess -fstack-protector-strong -Wformat -Wformat-security -o main.i
/usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed main.i -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase-strip main.o -version -fstack-protector-strong -Wformat -Wformat-security -o main.s
as -v --64 -o main.o main.s
उबंटू में परीक्षण 19.04 amd64, GCC 8.3.0।
-S विकल्प का उपयोग करें:
gcc -S program.c
से: http://www.delorie.com/djgpp/v2faq/faq8_20.html
gcc -c -g -Wa, -a, -ad [अन्य GCC विकल्प] foo.c> foo.lst
PhirePhly के जवाब के विकल्प में या सभी के रूप में सिर्फ -S का उपयोग करें।
यहां आपके विंडोज पर किसी भी सी प्रोग्राम के असेंबली कोड को देखने / प्रिंट करने के चरण दिए गए हैं
कंसोल / टर्मिनल / कमांड प्रॉम्प्ट:
सी कोड एडिटर में सी प्रोग्राम को कोडब्लॉक की तरह लिखें और एक्स्टेंशन .c से सेव करें
इसे संकलित करें और चलाएं।
एक बार सफलतापूर्वक चलाने के बाद, उस फ़ोल्डर पर जाएं जहां आपने अपना gcc संकलक स्थापित किया है और इसे दे
'.c' फ़ाइल की '.s' फ़ाइल प्राप्त करने के लिए निम्नलिखित कमांड
C: \ gcc> gcc -S पूर्ण पथ C फ़ाइल ENTER की
एक उदाहरण कमांड (मेरे मामले में)
C: \ gcc> gcc -SD: \ Aa_C_Certified \ alternate_letters.c
यह '.s' फ़ाइल की 'मूल .c' फ़ाइल को आउटपुट करता है
४। इसके बाद, निम्न कमांड टाइप करें
C; \ gcc> cpp filename.s ENTER
उदाहरण कमांड (मेरे मामले में)
C; \ gcc> cpp alternate_letters.s
यह आपके C प्रोग्राम की संपूर्ण असेंबली भाषा कोड को प्रिंट / आउटपुट करेगा।
एक विकल्प के रूप में "-S" का उपयोग करें। यह टर्मिनल में असेंबली आउटपुट प्रदर्शित करता है।
gcc foo.c -masm=intel -fverbose-asm -O3 -S -o- |less
। -S
अपने स्वयं के निर्माण पर foo.s
।
हाल ही में मैं एक कार्यक्रम में प्रत्येक फ़ंक्शन की असेंबली जानना चाहता
था कि यह मैंने कैसे किया।
$ gcc main.c // main.c source file
$ gdb a.exe // gdb a.out in linux
(gdb) disass main // note here main is a function
// similary it can be done for other functions
यहाँ gcc का उपयोग करके C के लिए एक समाधान दिया गया है:
gcc -S program.c && gcc program.c -o output
यहां पहला भाग प्रोग्राम के असेंबली आउटपुट को प्रोग्राम के समान फ़ाइल नाम में संग्रहीत करता है, लेकिन बदले हुए .s एक्सटेंशन के साथ, आप इसे किसी भी सामान्य टेक्स्ट फ़ाइल के रूप में खोल सकते हैं।
यहां दूसरा भाग आपके प्रोग्राम को वास्तविक उपयोग के लिए संकलित करता है और एक निर्दिष्ट फ़ाइल नाम के साथ आपके प्रोग्राम के लिए एक निष्पादन योग्य बनाता है।
ऊपर इस्तेमाल किया जाने वाला program.c आपके प्रोग्राम का नाम है और आउटपुट उस निष्पादन योग्य का नाम है जिसे आप उत्पन्न करना चाहते हैं।
BTW यह StackOverFlow पर मेरी पहली पोस्ट है: -}