C++從代碼到可執行文件的四個階段


 從代碼到可執行程序的四個階段:

預處理-->編譯-->匯編-->鏈接

  

一步完成從代碼到可執行程序:

c程序來說使用 

gcc name.c -o name.exe 

執行命令后會生成可執行文件 name.exe。

c++程序來使用

g++ name.cpp -o name.exe

執行命令后生成可執行文件name.exe。 

 

gcc和g++的區別:

 對C程序來說,gcc使用c代碼的方式編譯 ,而g++則使用C++代碼的方式編譯。注意:使用C++的方式編譯C代碼可能會出錯。

對C++程序來說,兩者沒有差別。 

 

四個階段完成從代碼到可執行程序:

源文件b.cpp代碼如下:

  #include<iostream>
  using namespace std;

  /*
      這是一個注釋!
  */
  int main()
  {
      cout<<"c++ program!"<<endl;
      system("pause");
      return 0;
  }

 

1、預處理

g++  -E(大寫)  name.cpp

-E 選項用來對原代碼做預處理操作。使用 g++ -E b.cpp命令后,只會將預處理指操作的結果輸出到屏幕,若想保存操作結果則要搭配-o使用。

 預處理主要處理源文件和頭文件中以#開頭的命令(#<iostream>等),並刪除程序中的注釋信息等。

運行 g++  -E  b.cpp  -o  b.i  會生成一個b.i文件

打開b.i文件后可以看到一些信息,發現其中注釋已經被刪掉了,頭文件被替換為好多行代碼。

# 1 "b.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "b.cpp"
# 1 "C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream" 1 3
# 36 "C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream" 3
       
# 37 "C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream" 3

# 1 "C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 1 3
# 236 "C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 3

# 236 "C:/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 3
namespace std
{
  typedef long long unsigned int size_t;
  typedef long long int ptrdiff_t;
  typedef decltype(nullptr) nullptr_t;
            .....
            .....
            .....
            .....
            .....
  extern istream cin;
  extern ostream cout;
  extern ostream cerr;
  extern ostream clog;
  extern wistream wcin;
  extern wostream wcout;
  extern wostream wcerr;
  extern wostream wclog;
  static ios_base::Init __ioinit;

}
# 2 "b.cpp" 2
# 3 "b.cpp"
using namespace std;

int main()
{
 cout<<"c++ program!"<<endl;
 system("pause");
 return 0;
}

 

2、編譯

g++  -S(大寫)  name.cpp / name.i

使用該g++ -S b.cpp 后會自動生成b.s匯編代碼文件,將c++代碼翻譯為匯編代碼。

g++ -S指令並非必須經過預處理后的.i文件,-S選項的功能是令GCC編譯器將指定文件預處理至編譯階段結束。

也就是說g++ -S可以處理.i文件,也可以處理原代碼文件。

 

    .file    "b.cpp"
    .text
    .section .rdata,"dr"
_ZStL19piecewise_construct:
    .space 1
.lcomm _ZStL8__ioinit,1,1
    .def    __main;    .scl    2;    .type    32;    .endef
.LC0:
    .ascii "c++ program!\0"
.LC1:
    .ascii "pause\0"
    .text
    .globl    main
    .def    main;    .scl    2;    .type    32;    .endef
    .seh_proc    main
main:
.LFB1573:
    pushq    %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe    %rbp, 0
    subq    $32, %rsp
    .seh_stackalloc    32
    .seh_endprologue
    call    __main
    leaq    .LC0(%rip), %rdx
    movq    .refptr._ZSt4cout(%rip), %rcx
    call    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
    movq    .refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(%rip), %rdx
    movq    %rax, %rcx
    call    _ZNSolsEPFRSoS_E
    leaq    .LC1(%rip), %rcx
    call    system
    movl    $0, %eax
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .def    __tcf_0;    .scl    3;    .type    32;    .endef
    .seh_proc    __tcf_0
__tcf_0:
.LFB2063:
    pushq    %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe    %rbp, 0
    subq    $32, %rsp
    .seh_stackalloc    32
    .seh_endprologue
    leaq    _ZStL8__ioinit(%rip), %rcx
    call    _ZNSt8ios_base4InitD1Ev
    nop
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .def    _Z41__static_initialization_and_destruction_0ii;    .scl    3;    .type    32;    .endef
    .seh_proc    _Z41__static_initialization_and_destruction_0ii
_Z41__static_initialization_and_destruction_0ii:
.LFB2062:
    pushq    %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe    %rbp, 0
    subq    $32, %rsp
    .seh_stackalloc    32
    .seh_endprologue
    movl    %ecx, 16(%rbp)
    movl    %edx, 24(%rbp)
    cmpl    $1, 16(%rbp)
    jne    .L6
    cmpl    $65535, 24(%rbp)
    jne    .L6
    leaq    _ZStL8__ioinit(%rip), %rcx
    call    _ZNSt8ios_base4InitC1Ev
    leaq    __tcf_0(%rip), %rcx
    call    atexit
.L6:
    nop
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .def    _GLOBAL__sub_I_main;    .scl    3;    .type    32;    .endef
    .seh_proc    _GLOBAL__sub_I_main
_GLOBAL__sub_I_main:
.LFB2064:
    pushq    %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe    %rbp, 0
    subq    $32, %rsp
    .seh_stackalloc    32
    .seh_endprologue
    movl    $65535, %edx
    movl    $1, %ecx
    call    _Z41__static_initialization_and_destruction_0ii
    nop
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .section    .ctors,"w"
    .align 8
    .quad    _GLOBAL__sub_I_main
    .ident    "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0"
    .def    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc;    .scl    2;    .type    32;    .endef
    .def    _ZNSolsEPFRSoS_E;    .scl    2;    .type    32;    .endef
    .def    system;    .scl    2;    .type    32;    .endef
    .def    _ZNSt8ios_base4InitD1Ev;    .scl    2;    .type    32;    .endef
    .def    _ZNSt8ios_base4InitC1Ev;    .scl    2;    .type    32;    .endef
    .def    atexit;    .scl    2;    .type    32;    .endef
    .section    .rdata$.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, "dr"
    .globl    .refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
    .linkonce    discard
.refptr._ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_:
    .quad    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
    .section    .rdata$.refptr._ZSt4cout, "dr"
    .globl    .refptr._ZSt4cout
    .linkonce    discard
.refptr._ZSt4cout:
    .quad    _ZSt4cout

 

 

 

3、匯編

g++  -c  name.cpp / name.s

使用g++ -c b.s對匯編代碼進行匯編會生成相應的目標文件(b.o文件)

目標文件為二進制文件,由於尚未經過鏈接操作,所以無法直接運行。

 

4、鏈接

  g++  b.o  -o  b.exe 

將得到的b.o文件經過鏈接(一些函數和全局變量等)后便得到了可執行程序。

並不需要在g++添加任何選項,g++會在b.o的基礎上完成鏈接操作。

 

 

 

 

 

 

參考鏈接:http://c.biancheng.net/view/7960.html

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM