আপনি সিসি / সি ++ উত্স থেকে জিসিসিতে এসেম্বলারের আউটপুট পাবেন কীভাবে?


378

এক এই কিভাবে কাজ করে?

যদি আমি বিশ্লেষণ করতে চাই যে কীভাবে কোনও কিছু সংকলিত হচ্ছে, আমি কীভাবে নির্গত সমাবেশ কোড পাব?


8
Asm আউটপুটকে মানব পাঠযোগ্য করে তোলার বিষয়ে টিপসের জন্য , আরও দেখুন: জিসিসি / ঝনঝন সমাবেশ আউটপুট থেকে কীভাবে "শব্দ" সরিয়ে ফেলবেন?
পিটার কর্ডেস

উত্তর:


420

-SGcc (অথবা g ++) বিকল্পটি ব্যবহার করুন ।

gcc -S 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 ব্যবহার করে পাবেন স্তরে কিছু ইঙ্গিত দিতে হবে।


3
যদিও এটি সঠিক, আমি সিআর ম্যাকডোনফের উত্তরটি আরও দরকারী বলে খুঁজে পেয়েছি।
Rhys Ulerich

3
একটি অতিরিক্ত ব্যবহার: লিনাক্সে নাসমের সাথে সামঞ্জস্যপূর্ণ ইন্টেল সিনট্যাক্সে অবজেক্ট ডাম্প পেতে objজডাম্প-এম ইন্টেল-এস --ডিসেসেম্বল হেলিওর্ল্ড> হেলিওরল্ড.ডাম্প।
টাচস্টোন

2
আপনার নিখুত / চেক করার জন্য একটি একক কার্যকারিতা থাকে, তাহলে আপনি অনলাইনে ইন্টারেক্টিভ সি ++ কম্পাইলার অর্থাৎ করে দেখুন দিতে পারেন godbolt
fiorentinoing

1
@touchStone: গ্যাস .intel_syntaxহয় না NASM সঙ্গে সামঞ্জস্যপূর্ণ । এটি এমএএসএম এর মতো (যেমন mov eax, symbolকোনও লোড, এটি নাসেমের বিপরীতে যেখানে এটি mov r32, imm32ঠিকানার ঠিকানা), তবে এমএএসএম এর সাথে পুরোপুরি সামঞ্জস্যপূর্ণ নয়। আমি এটি পড়ার জন্য একটি দুর্দান্ত ফর্ম্যাট হিসাবে অত্যধিক প্রস্তাব দিচ্ছি, বিশেষত আপনি যদি এনএএসএম সিনট্যাক্সে লিখতে চান তবে। objdump -drwC -Mintel | lessবা gcc foo.c -O1 -fverbose-asm -masm=intel -S -o- | lessদরকারী। ( জিসিসি / ঝনঝন সমাবেশ আউটপুট থেকে কীভাবে "শব্দ" সরিয়ে ফেলবেন তা দেখুন? ) -masm=intelঝাঁকুনির সাথেও কাজ করে।
পিটার

3
আরও ভাল ব্যবহারgcc -O -fverbose-asm -S
বেসাইল স্টারিঙ্কেভিচ

172

এটি আরও সহজেই দেখতে পাবে যে রেখাঙ্কনগুলি কোন কোড উত্পন্ন করে: এটি সহজেই আন্তঃবিবাহিত সি কোড + লাইন নম্বরগুলির সাথে সমাবেশ কোড উত্পন্ন করবে

# 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 তম পৃষ্ঠা)।


3
(এটি আসলে পৃষ্ঠায় (সংখ্যাযুক্ত) 3 (যা
পিডিএফের

1
দুঃখের বিষয়, asওএস এক্স এ এই পতাকাগুলি জানেন না। এটি যদি করা থাকে তবে -Waঅপশনগুলি পাস করার জন্য আপনি সম্ভবত এটি এক-লাইন করতে পারেন as
গ্রুমড্রিগ

23
g++ -g -O0 -c -fverbose-asm -Wa,-adhln test.cpp > test.lstএটির সংক্ষিপ্ত সংস্করণ হবে।
কিংবদন্তি

4
আপনি উভয় gcc -c -g -Wa,-ahl=test.s test.cবাgcc -c -g -Wa,-a,-ad test.c > test.txt
ফুক্লভি

1
একটি ব্লগ পোস্টে পৌরাণিক কাহিনী এবং Lu'u মত এক-কমান্ড সংস্করণ সহ আরো বিস্তারিত এই ব্যাখ্যা, পোস্ট করা হয়েছে। তবে কেন -O0? এটি এমন লোড / স্টোরগুলিতে পূর্ণ যা কোনও মান ট্র্যাক করা কঠিন করে তোলে এবং অপ্টিমাইজড কোডটি কতটা কার্যকর হবে সে সম্পর্কে আপনাকে কিছু জানায় না।
পিটার কর্ডস

51

নিম্নলিখিত কমান্ড লাইনটি ক্রিশ্চিয়ান গারবিনের ব্লগ থেকে এসেছে

g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt

আমি উইন-এক্সপি-তে একটি ডস উইন্ডো থেকে জি ++ চালিয়েছিলাম, একটি নিয়মিত বিপরীতে imp

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'

আউটপুটটি মূল সি ++ কোডের সাথে সংযুক্ত জেনারেট কোড সংযোজন করা হয় (সি ++ কোডটি উত্পন্ন এএসএম স্ট্রিমের মন্তব্য হিসাবে দেখানো হয়)

  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আপনার প্রকল্পটি নির্মাণের সময় আপনি প্রকৃতপক্ষে ব্যবহার করেন এমন কমপক্ষে অথবা অপ্টিমাইজেশন বিকল্পগুলি ব্যবহার করুন, আপনি যদি দেখতে চান যে জিসিসি আপনার কোডটি কীভাবে অনুকূল করে। (অথবা আপনি যদি এলটিও ব্যবহার করেন, যেমনটি আপনার করা উচিত, তবে আপনি কী পেতে পারেন তা দেখতে আপনাকে লিঙ্কার আউটপুটটি আলাদা করতে হবে))
পিটার

27

-এস সুইচটি ব্যবহার করুন

g++ -S main.cpp

বা জিসিসি সহ

gcc -S main.c

আরো দেখুন এই


7
সাধারণত জিজ্ঞাসিত প্রশ্নাগুলি পরীক্ষা করুন: "আপনার নিজের প্রোগ্রামিং প্রশ্নটি জিজ্ঞাসা করা এবং উত্তর দেওয়াও পুরোপুরি ঠিক"। পয়েন্টটি হ'ল এখন স্ট্যাকওভারফ্লোতে অন্যদের জন্য একটি উত্স হিসাবে প্রশ্নোত্তর রয়েছে।
স্টিভ জেসোপ

এবং সম্ভবত অন্য কেউ এসে আপনাকে আরও ভাল উত্তর দিয়ে চমকে দেবে, যদিও আমার সময়ে সময়ে কিছুটা
ভার্জোজ

এমনকি উত্তর আপনার নিজের প্রশ্ন বোতাম আছে।
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

13

আপনি যা দেখতে চান তা যদি আউটপুটের সাথে সংযোগ স্থাপনের উপর নির্ভর করে তবে আউটপুট অবজেক্ট ফাইল / এক্সিকিউটেবলের ওপজডাম্প উপরোক্ত জিসিসি-এস ছাড়াও কার্যকর হতে পারে। এখানে লোরেন মেরিটের একটি খুব দরকারী স্ক্রিপ্ট যা ডিফল্ট অ্যাজডাম্প সিনট্যাক্সকে আরও পঠনযোগ্য নাসম সিনট্যাক্সে রূপান্তর করে:

#!/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;

আমি সন্দেহ করি এটি জিসিসি-এস এর আউটপুটটিতেও ব্যবহার করা যেতে পারে।


2
তবুও, এই স্ক্রিপ্টটি একটি নোংরা হ্যাক যা পুরোপুরি সিনট্যাক্সকে রূপান্তর করে না। যেমন mov eax,ds:0x804b794খুব নাসমিশ নয় M এছাড়াও, কখনও কখনও এটি শুধু দরকারী তথ্য রেখাচিত্রমালা: movzx eax,[edx+0x1]অনুমান করা মেমরির প্রতীক ছিল কিনা পাঠক ছেড়ে byteবা word
Ruslan

প্রথমে এনএএসএমobjconv সিনট্যাক্সে বিচ্ছিন্ন করতে, আগ্নার ফগ ব্যবহার করুন । আপনি এটি আউটপুট ফাইল = দিয়ে স্টডআউটে বিচ্ছিন্ন /dev/stdoutকরতে পারেন, যাতে আপনি lessদেখার জন্য পাইপ করতে পারেন । এছাড়াও রয়েছে ndisasm, তবে এটি কেবল সমতল বাইনারিগুলি বিচ্ছিন্ন করে দেয় এবং অবজেক্ট ফাইলগুলি (ELF / PE) সম্পর্কে জানে না।
পিটার কর্ডস

9

সবাই যেমন উল্লেখ করেছে, -Sজিসিসিতে বিকল্পটি ব্যবহার করুন । আমি আরও যোগ করতে চাই যে আপনি অপ্টিমাইজেশান বিকল্পগুলি যোগ করেন বা না করেন তার উপর নির্ভর করে (বন্যভাবে!) ফলাফলগুলি পরিবর্তিত হতে পারে (কোনওটির -O0জন্য নয়, -O2আগ্রাসী অপ্টিমাইজেশনের জন্য)।

বিশেষত আরআইএসসি আর্কিটেকচারে, সংকলক প্রায়শই অপ্টিমাইজেশন করার ক্ষেত্রে কোডটিকে প্রায় স্বীকৃতি ছাড়াই রূপান্তরিত করে। ফলাফলগুলি দেখার জন্য এটি চিত্তাকর্ষক এবং আকর্ষণীয়!


9

ঠিক আছে, সবাই যেমন বলেছে, -S বিকল্পটি ব্যবহার করুন। আপনি যদি সেভ-টেম্পস বিকল্পটি ব্যবহার করেন তবে আপনি প্রিপ্রোসেসড ফাইল ( .i), সমাবেশ ফাইল ( .s) এবং অবজেক্ট ফাইল (*। ও )ও পেতে পারেন। (তাদের প্রত্যেককে -E, -S এবং -c ব্যবহার করে পান get)


8

পূর্বে উল্লিখিত হিসাবে, -S পতাকা দেখুন।

ফ্ল্যাগের '-ফম্প্প-ট্রি' পরিবারকে, বিশেষত '-ফডম্প-ট্রি-অল' এর দিকে নজর রাখাও মূল্যবান, এটি আপনাকে সিসির কয়েকটি মধ্যবর্তী রূপ দেখতে দেয়। এগুলি প্রায়শই এসেম্বলারের (কমপক্ষে আমার কাছে) চেয়ে বেশি পঠনযোগ্য হতে পারে এবং আপনাকে দেখতে দেয় যে কীভাবে অপ্টিমাইজেশন পাস হয়।


8

আপনি যদি এলএলভিএম সমাবেশের সন্ধান করছেন:

llvm-gcc -emit-llvm -S hello.c

8

আমি উত্তরগুলির মধ্যে এই সম্ভাবনাটি দেখতে পাচ্ছি না কারণ সম্ভবত প্রশ্নটি ২০০৮ সালের, তবে 2018 সালে আপনি ম্যাট গোল্ডবোল্টের অনলাইন ওয়েবসাইট https://godbolt.org ব্যবহার করতে পারেন

আপনি স্থানীয়ভাবে ক্লিট গিট করতে এবং তার প্রকল্প https://github.com/mattgodbolt/compiler-explorer চালাতে পারেন


8

-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 এ পরীক্ষিত, জিসিসি 8.3.0।




3

এই কম্যান্ডের আউটপুট

আপনার উইন্ডোজে যে কোনও সি প্রোগ্রামের অ্যাসেম্বলি কোডটি দেখতে / মুদ্রণের জন্য পদক্ষেপগুলি এখানে রয়েছে

কনসোল / টার্মিনাল / কমান্ড প্রম্পট:

  1. কোডব্লকসের মতো সি কোড সম্পাদকে সি প্রোগ্রাম লিখুন এবং এটি একটি এক্সটেনশন .c দিয়ে সংরক্ষণ করুন

  2. সংকলন এবং এটি চালান।

  3. একবার সফলতার সাথে চালানোর পরে, আপনি যে ফোল্ডারে আপনার জিসিসি সংকলকটি ইনস্টল করেছেন সেখানে যান এবং দিন

    '.c' ফাইলের একটি '.s' ফাইল পেতে নিম্নলিখিত আদেশটি অনুসরণ করুন

    C: \ gcc> gcc -S C ফাইল ENTER- এর সম্পূর্ণ পাথ

    একটি উদাহরণ কমান্ড (আমার ক্ষেত্রে হিসাবে)

    সি: \ জিসিসি> জিসিসি-এসডি: \ এএসিসি_প্রাপ্ত tern বিকল্প_লেটারস.সি

    এটি একটি '.s' মূল '.c' ফাইলের ফাইল আউটপুট করে

ঘ। এর পরে নিম্নলিখিত কমান্ডটি টাইপ করুন

C; \ gcc> cpp filename.s ENTER

উদাহরণ কমান্ড (আমার ক্ষেত্রে হিসাবে)

C; \ gcc> cpp alternate_letters.s

এটি আপনার সি প্রোগ্রামের পুরো বিধানসভা ভাষার কোড প্রিন্ট / আউটপুট দেবে।


2

বিকল্প হিসাবে "-S" ব্যবহার করুন। এটি টার্মিনালে সমাবেশের আউটপুট প্রদর্শন করে।


টার্মিনাল প্রদর্শন করতে, ব্যবহার করুন gcc foo.c -masm=intel -fverbose-asm -O3 -S -o- |less-Sনিজের তৈরি করে foo.s
পিটার কর্ডেস

2

সম্প্রতি আমি একটি প্রোগ্রামে প্রতিটি ফাংশনগুলির সমাবেশটি জানতে চেয়েছিলাম
এটি এটি আমি কীভাবে করেছি।

$ 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

2

সিসির জন্য জিসিসি ব্যবহার করে একটি সমাধান এখানে দেওয়া হয়েছে:

gcc -S program.c && gcc program.c -o output
  1. এখানে প্রথম অংশ প্রোগ্রামের সমাবেশের আউটপুটটিকে একই ফাইল নামে প্রোগ্রাম হিসাবে সংরক্ষণ করে তবে পরিবর্তিত .s এক্সটেনশন সহ, আপনি এটি কোনও সাধারণ পাঠ্য ফাইল হিসাবে খুলতে পারেন।

  2. এখানে দ্বিতীয় অংশটি আপনার প্রোগ্রামকে প্রকৃত ব্যবহারের জন্য সংকলন করে এবং একটি নির্দিষ্ট ফাইলের নাম সহ আপনার প্রোগ্রামের জন্য একটি এক্সিকিউটেবল জেনারেট করে।

Program.c উপরে ব্যবহৃত আপনার প্রোগ্রাম নাম এবং আউটপুট এক্সিকিউটেবল আপনি জেনারেট করতে চান নাম।

বিটিডাব্লিউ স্ট্যাকওভারফ্লোতে এটি আমার প্রথম পোস্ট: -}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.