GCC编译

article/2025/10/2 16:04:47

目录

一、常用命令

1、简单编译

2、多个程序文件的编译

3、检错

4、库文件连接 

 二、GCC编译

1、准备工作

2、编译过程

3、汇编 

4、链接

三、分析ELF文件

1、ELF文件的段

 2、反汇编ELF

四、总结


一、常用命令

1、简单编译

(1)创建文件,输入如下代码,并且编译

#include<stdio.h>
int main(void)
{printf("Hello World!\n");return 0;
}

步骤: 

(2)预处理

(3)编译使之成为汇编代码

预处理后,对生成的test.i文件编译,生成汇编代码

(4)汇编

对生成的汇编代码文件test.s,将其编译为目标文件

 (5)连接

将程序的目标文件与所需的所有附加目标文件连接起来(包括静态连接库和动态连接库),生成可执行文件

(6)执行

2、多个程序文件的编译

3、检错

(1)按照ANSI/ISO C语言标准进行编译器诊断

(2)在所有产生警告的地方停止编译,要求修改

(3)

4、库文件连接 

(1)编译成可执行文件

进行编译test.c为目标文件

(2)链接

把所有目标文件链接成可执行文件

(3)强制链接时使用静态链接库

 

 二、GCC编译

1、准备工作

创建工作目录test0,然后用gedit文本编辑器生成一个.c文件

源代码:

#include <stdio.h>
//此程序很简单,仅仅打印一个 Hello World 的字符串。
int main(void)
{
printf("Hello World! \n");
return 0;
}

 

2、编译过程

(1)预处理

   将.c文件预处理生成.i文件

 hello.i文件可作为普通文本文件打开查看

(2)编译

将预处理生成的hello.i文件编译生成汇编程序hello.s

hello.s文件中为汇编代码

3、汇编 

将编译生成的hello.s文件汇编生成目标文件hello.o

4、链接

先进行连接,使用gcc hello.c-o hello会进行动态库进行连接

使用size查看大小

用ldd命令查看一个可执行程序依赖的共享库

 可以看出可执行文件连接了很多动态库

使用命令 gcc -static hello.c -o hello 会进行静态库链接

使用size命令查看ELF文件的大小

用ldd命令查看一个可执行程序依赖的共享库

 可以看出text的尺寸变大且没有链接动态库

三、分析ELF文件

链接后生成的文件为ELF格式的可执行文件,一个ELF文件通常被链接为不同的段,常见的段譬如.text、.data、.rodata、.bss 等段

1、ELF文件的段

ELF 文件格式如下图所示,位于 ELF Header 和 Section Header Table 之间的都 是段(Section)。一个典型的 ELF 文件包含下面几个段:

.text:已编译程序的指令代码段。

.rodata:ro 代表 read only,即只读数据(譬如常数 const)。

.data:已初始化的 C 程序全局变量和静态局部变量。

.bss:未初始化的 C 程序全局变量和静态局部变量。

.debug:调试符号表,调试器用此段的信息帮助调试

 使用 readelf -S查看各个section的信息: 

 2、反汇编ELF

ELF文件无法被当做普通文本文件打开,需要使用反汇编的方法查看一个ELF文件包含的指令和数据。

使用 objdump -D 对其进行反汇编如下:

objdump -D hell

使用 objdump -S 将其反汇编并且将其 C 语言源代码混合显示:

$ gcc -o hello -g hello.c //要加上-g 选项
$ objdump -S

四、总结

在完成这次的练习中,我了解学习了有关GCC的常用命令,熟练了如何去进行预处理、编译、汇编、链接的相关操作,并且理解了有关静态库链接、动态库链接的概念和ELF文件的结构与查看方式,对于我学习Linlinux有很大的帮助。


http://chatgpt.dhexx.cn/article/2GYn3a3R.shtml

相关文章

C++学习之gcc编译四步

C学习之gcc编译四步 一、linux下编写Hello World&#xff01;代码文件二、gcc编译四步1.预处理&#xff08;Preprocessing&#xff09;2.编译&#xff08;Compilation&#xff09;3.汇编&#xff08;Assembly&#xff09;4.链接&#xff08;Linking&#xff09; 三、执行四、gc…

Linux GCC编译详细

在Linux中使用gcc编译“hello.c”文件&#xff0c;只须使用最简单的指令&#xff0c;如下所示 $gcc hello.c -o hello 事实上&#xff0c;上述过程可以分解成四个部分&#xff1a;预处理&#xff08;预编译&#xff09;、编译、汇编、链接 一、预处理 首先是源代码文件“he…

gcc的编译过程

目录 一、gcc的编译过程 1.预处理 2.编译 3.汇编 4.连接 一、gcc的编译过程 平时使用gcc&#xff0c;我们新手小白似乎只会使用它编译生成./a.out。 gcc hello.c 或者就是给生成的程序一个别名。 gcc hello.c -o hello 但是gcc还有很多的用处&#xff0c;而且了解gcc的…

多线程和异步的区别

首先说明&#xff0c;这里介绍的区别可能有些浅显&#xff0c;内部更深层的原理&#xff0c;说实在的&#xff0c;我现在有点理解不了&#xff0c;大家可以参考以下两个地方&#xff0c;主要是以C#为主要语言&#xff1a; c#关于异步编程&#xff1f; C# 彻底搞懂async/await …

单线程与多线程使用场景

多线程使用时机 出现CPU资源浪费&#xff08;CPU空转&#xff09;的时候才适用多线程&#xff0c;每个核心在同一时刻只能处理一个线程&#xff0c;而逻辑处理器则是通过CPU的并发来模拟出的核心 单线程与多线程使用情况 适用单线程的情况 CPU全力执行&#xff0c;没有产生…

多线程与并发 - 进程和线程的区别

进程和线程的由来&#xff1a; 进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位 所有与进程相关的资源&#xff0c;都被记录在PCB中进程是抢占处理机的调度单位&#xff1b;线程属于某个进程&#xff0c;共享其资源线程只由堆栈寄存器、程序计数器和线程控制表&…

多线程并发和并行的区别

背景 对于java开发从业人员来说&#xff0c;并发编程是绕不开的话题&#xff0c;juc并发包下提供了一系列多线程场景解决方案。  随着jdk1.8的普及&#xff0c;多线程处理问题&#xff0c;除了使用使用线程池(ExecutorService)&#xff0c;很多人选择了parallelStream() 并行流…

多线程与单线程理解

多线程与单线程理解 进程与线程的关系 进程是计算机程序执行一次过程的接班单位&#xff0c;即正在执行的程序&#xff08;QQ&#xff09;&#xff0c;一个应用程序可以包含多个进程&#xff08;QQ的不同页面信息&#xff09; 线程是进程的基本单元&#xff0c;一个进程至少包…

线程和进程的区别与联系以及单线程多进程与单进程多线程的区别

线程和进程 概念 进程&#xff08;process&#xff09;&#xff1a;是指具有已一定功能的独立程序&#xff0c;是系统资源分配的基本单位&#xff0c;在内存中有其完备的数据空间和代码空间&#xff0c;拥有完整的虚拟空间地址。一个进程所拥有的数据和变量只属于它自己。 线…

单线程与多线程的区别?

什么是进程&#xff1f; 当一个程序开始运行时&#xff0c;它就是一个进程&#xff0c;进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 什么是线程&#xff1f; 线程是程序中的一个执行流&#xff0c;每个线程都有自己的专有寄存器…

单线程与多线程

目录 多线程的创建 方式一&#xff1a;继承Thread类 方式二&#xff1a;实现Runnablel接口 方式三&#xff1a;JDK5.0新增Callable接口 Thread的常用方法 线程安全 线程同步 线程通信 线程池【重点】 定时器 补充知识&#xff1a;并发、并行 生命周期 什么是线程&…

什么是单线程和多线程,单线程与多线程的区别

什么是进程&#xff1f; 当一个程序开始运行时&#xff0c;它就是一个进程&#xff0c;进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 什么是线程&#xff1f; 线程是程序中的一个执行流&#xff0c;每个线程都有自己的专有寄存器…

理解单线程和多线程的区别

单线程和多线程 首先我们都知道线程是隶属于进程的,单线程就是程序中只有一个线程,多线程就是程序中有多个线程.通过连个例子理解多线程和单线程. (一)单线程 创建包:package com.ffyc.javathread; 创建类:public class Sample { } package com.ffyc.javathread; public c…

ubuntu卸载已安装软件

1.查看已安装软件列表 dpkg -l dpkg -l | grep baidu # 软件包查询筛选# 另外&#xff0c;软件安装也使用dpkg命令 sudo dpkg -i xxxx.deb2.卸载指定软件包 sudo apt-get purge baidunetdisk # 卸载指定软件 sudo apt-get autoremove # 清理不需要的文件 sudo apt-get autoc…

Ubuntu20.04 卸载软件

Ubuntu20.04卸载软件相当的简单&#xff0c; 一 用命令行卸载 sudo apt-get remove --purge 软件名 这样不仅可以卸载掉软件&#xff0c;而且可以清理配置 二 在图形界面卸载软件 首先打开设置 打开应用程序 在其中找到你要卸载的软件 然后点击右上角的 在软件中打开 然后…

Linux bash卸载软件,Ubuntu卸载软件的4种方法

前言 本文重点介绍Ubuntu卸载软件的4种方法。他们分别是图形化界面的synaptic、自动解决依赖关系的apt-get,处理依赖关系更强大的aptitude,还有安装本地deb包的dpkg。 方法一: Ubuntu使用synaptic图形化界面管理软件 oucanrong@zcwyou:~$ sudo apt-get install synaptic -y 以…

Ubuntu卸载软件方式

1、终端输入&#xff1a; dpkg --list 显示出电脑上所有的软件包 左边就是软件名字&#xff0c;中间是版本名 2、在终端上输入命令sudo apt --purge remove 包名 例如我要卸载smartgit 即可

Ubuntu卸载软件

1、利用"软件中心"卸载 在Ubuntu收藏栏中打开软件中心&#xff0c;在已安装的软件中找到要卸载的软件&#xff0c;点击“移除”按钮即可。 提示&#xff1a;需要输入用户密码。 2、在终端中卸载 2.1、找到软件 有些软件在“软件中心”中是找不到的。还是需要用终端…

Ubuntu卸载软件相关命令

查看安装的软件 dpkg -l 查看软件版本 dpkg -l | grep xxx # xxx为软件名称&#xff0c;例如 virtualbox 查看包是否安装 dpkg-query -l *package-name* 例如 virtualbox dpkg -s package-name 例如 virtualbox 列出你系统中安装的所有包&#xff0c;同样可以通过grep…

Ubuntu命令卸载软件

1.打开一个终端&#xff0c;输入dpkg --list ,按下Enter键&#xff0c;终端输出以下内容&#xff0c;显示的是你电脑上安装的所有软件。 2.在终端中找到你需要卸载的软件的名称&#xff0c;列表是按照首字母排序的。 3.在终端上输入命令sudo apt-get --purge remove 包名…