C++预编译、编译、汇编、链接详解

一、准备阶段

  • g++编译环境,配置好环境变量
  • 新建一个helloworld.cpp
cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
    cout << "Hello, world!" << endl;
    return 0;
}
  • 命令查看

    cpp 复制代码
     g++ --help

二、预编译

预处理阶段对自定义和预定义的宏进行展开,把包含的头文件内容插入到当前源文件,并根据预处理指令包含不同的代码,或者设置设置传递给编译器的参数。

使用gcc的-E和-v选项来查看整个预处理过程。-E选项表示只对源文件做预处理,-v选项表示显示详细的预处理过程,-o选项表示将预处理后的结果输出到helloworld.i文件中

文件 helloworld.i 部分

cpp 复制代码
# 1 "helloworld.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "helloworld.cpp"
# 1 "D:/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/iostream" 1 3
# 36 "D:/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/iostream" 3
       
# 37 "D:/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/iostream" 3

# 1 "D:/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/x86_64-w64-mingw32/bits/c++config.h" 1 3
# 186 "D:/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/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;

三、编译

编译阶段由编译器ccl把预处理后的文件内容转换成汇编程序。我们可以使用gcc的-S选项来实现编译的过程。-S选项便是只做编译处理

cpp 复制代码
.file	"helloworld.cpp"
.lcomm _ZStL8__ioinit,1,1
	.def	__main;	.scl	2;	.type	32;	.endef
	.section .rdata,"dr"
.LC0:
	.ascii "Hello, world!\0"
	.text
	.globl	main
	.def	main;	.scl	2;	.type	32;	.endef
	.seh_proc	main
main:
.LFB1048:
	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
	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:

四、汇编

汇编器as会把helloworld.s的内容翻译成机器指令,这些机器指令按照ELF(Executable and Linking Format)被打包成重定位的二进制目标文件。使用-c选项来实现目标文件的生成,使用type命令用于查看目标文件的信息。

五、链接

helloworld.c中引用了标准C库中的printf函数,所以在最后的链接阶段,ld链接器会把printf函数符号位于libc.so.6库中的重定位和符号表信息复制到最终的可执行文件helloworld 中。gcc链接时库的搜索路径在使用-v选项时会显示出来

六、运行

链接阶段生成helloworld.exe,直接运行

相关推荐
点云SLAM14 小时前
C++包装器之类型擦除(Type Erasure)包装器详解(4)
c++·算法·c++17·类型擦除·c++高级应用·c++包装器·函数包装
小尧嵌入式14 小时前
C++中的封装继承多态
开发语言·arm开发·c++
小年糕是糕手14 小时前
【C++同步练习】C++入门
开发语言·数据结构·c++·算法·pdf·github·排序算法
繁华似锦respect14 小时前
C++ 设计模式之工厂模式详细介绍
java·linux·c++·网络协议·设计模式
胖咕噜的稞达鸭14 小时前
算法入门:专题二分查找算法 模板总结 题目练手 :排序数组中查找元素的第一个和最后一个位置 第一个错误的版本 查找x的平方根 搜索插入位置 山脉数组的封顶索引
c语言·c++·算法·leetcode
未来之窗软件服务14 小时前
幽冥大陆(三十六)S18酒店门锁SDK rust语言——东方仙盟筑基期
开发语言·c++·rust·智能门锁·东方仙盟sdk·东方仙盟一体化
Emilia486.15 小时前
C++ 类与对象:解锁面向对象编程的核心密码(上)
开发语言·c++
Mr_WangAndy15 小时前
C++17 新特性_第二章 C++17标准库特性_std::invoke和std::invoke_result_t
c++·invoke·c++40周年·c++17新特性·invoke_result
无限进步_15 小时前
深入理解顺序表:从原理到完整实现
c语言·开发语言·数据结构·c++·算法·链表·visual studio
繁华似锦respect15 小时前
C++ 无锁队列(Lock-Free Queue)详细介绍
linux·开发语言·c++·windows·visual studio