预编译、编译、汇编、链接

0 前提

0.1 4个过程

预处理(preprocessing) ----------------- gcc -E
编译(compilation) ------------------ gcc -S
汇编(assembly) -------------------- as
连接(linking) --------------------- ld

0.2 gcc指令

  • -o:指定生成的输出文件;
  • -E:仅执行编译预处理;
  • -S:将C代码转换为汇编代码
  • -wall:显示警告信息;
  • -c:仅执行编译操作,不进行链接操作。

1. 预编译

1.1 预编译主要做以下4件事:

  • 展开所有头文件
  • 宏替换
  • 去掉注释
  • 条件编译
    • 即对#ifndef #endif进行判断检查

1.2 示例

源码:

//#include <stdio.h>
// #include "calculation.h"
#include "cpp_add.h"

#define TEST

#ifndef TEST
#define MAX_NUM 100
#else
#define MAX_NUM 10
#endif

int main()
{
    int x = 1;
    int y = 3;
    int a = MAX_NUM;

    square(a);

    return 0;
}

预编译:
在这里插入图片描述

2. 编译

2.1 编译主要做以下2件事

编译将代码转为汇编代码,并且这个步骤做了2件很重要的工作:

  • 编译器在每个文件中保存一个函数地址符表,该表中存储着当前文件内包含的各个函数的地址
  • 这一步要生成汇编代码,即一条一条的指令,而调用函数的代码会被编译成一条call指令,指令后面跟的是jmp指令的汇编代码地址,而jmp指令后面跟的才是“被调用的函数编译成汇编代码后的第一条指令”的地址,但是给call指令后面补充上地址的工作是链接时候的事情。

2.2 示例

还是上面的demo执行:gcc -S main.c
查看生成的main.s文件,也是汇编文件:

	.file	"main.c"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	$1, -12(%rbp)
	movl	$3, -8(%rbp)
	movl	$10, -4(%rbp)
	movl	-4(%rbp), %eax
	movl	%eax, %edi
	call	square@PLT
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	 1f - 0f
	.long	 4f - 1f
	.long	 5
0:
	.string	 "GNU"
1:
	.align 8
	.long	 0xc0000002
	.long	 3f - 2f
2:
	.long	 0x3
3:
	.align 8
4:

3. 汇编

汇编实际上指把汇编语言代码翻译成目标机器指令的过程。
目标文件由段组成。通常一个目标文件中至少有两个段:

  • 代码段:该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
  • 数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。

3.1 主要完成以下3件事

  • 根据汇编指令和特定平台,把汇编指令翻译成二进制形式;
  • 合并各个section,合并符号表;
  • 生成.o文件

3.2 示例

在这里插入图片描述

4. 链接

4.1 主要完成以下3件事:

  • 合并各个.obj文件的section,合并符号表,进行符号解析;
  • 符号地址重定位;
  • 生成可执行文件

4.2 示例

在这里插入图片描述

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值