zoukankan      html  css  js  c++  java
  • 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!"
    .LC1:
        .ascii "pause"
        .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

     

     

  • 相关阅读:
    分析facebook的AsyncDisplayKit框架,async-display使用async-transaction
    自制反汇编逆向分析工具 迭代第四版本
    自制反汇编逆向分析工具 迭代第三版本
    自制反汇编逆向分析工具 迭代第二版本
    分析facebook的AsyncDisplayKit框架中的Transaction的工作原理
    Oracle索引知识学习笔记
    PDF文件添加二维码水印教程
    图片添加二维码水印教程
    CAS单点登录之支持数据库认证
    CAS单点登录之服务端部署
  • 原文地址:https://www.cnblogs.com/dreammmz/p/13409800.html
Copyright © 2011-2022 走看看