77-C++编译链接过程

知识点:

1.磁盘:永久化存储,但是I/O速度慢

2.内存:支持程序执行所需要的真实空间

3.内存分为物理内存和虚拟内存

物理内存:内存条,I/O速度快

虚拟内存:虚拟就是假的,不是真正的内存,是磁盘上的一个交换空间,虚拟内存是在磁盘上提前划分了一块空间,当真实物理内存不够用时,将数据暂时存放到虚拟内存上

4.虚拟地址空间:逻辑上给到每个进程的执行空间

5.为什么真实物理内存会不够用?

6.程序执行时,会给每一个进程划分一个执行空间(虚拟地址空间),在32位系统上,大小是4G(2^32),注意:是逻辑上给了4G的空间,并不是真的给了4G的空间,如果当前进程用不到4G的空间,就会浪费,所以最大可以给到4G

7.虚拟地址如何产生?需要哪些步骤?

代码经过编译(预编译、编译、汇编的统称)生成二进制可重定位文件,然后经过链接生成二进制可执行文件,二进制可执行文件可以直接去执行,然后产生虚拟地址空间,虚拟地址空间通过地址映射,映射到真实的内存上面

8.虚拟地址空间的划分

在这里插入图片描述

0x0000 0000~0x0804 8000是预留空间, 不可以访问

一个进程会划分多个线程,每个线程默认分配10M的栈空间,如果没有划分多个线程就属于单一的执行线,默认分配10M的栈空间,如果多余10M,栈就崩了

一小块是存放环境变量、main函数的参数

***32位系统的虚拟地址空间为什么是4G?因为一共有32条地址总线,每一条线是0或者1,能标志的最小地址为0x0000 0000,能标志的最大地址为0xffff ffff,寻址范围就是从0x0000 0000~0xffff ffff,2^32=4G

9.什么是数据?什么是指令?判断一下下面哪些会生成数据?哪些会生成指令

框起来的都是数据,其他的都是指令

数据会存储在数据段(包括.bss段和.data段),指令会存储在指令段(代码段)

bss段存储没有初始化或者初始化为0的数据,data124578存储在bss段

data段存储有初始化且初始化值不为0的数据,data369存储在data段

其他都存储在指令段,包括main,大括号

在这里插入图片描述

并不是有了虚拟地址空间之后才划分了这些段,而是在二进制可执行文件中就已经划分了这些段,虚拟地址空间只是将二进制可执行文件中的对应段读取到虚拟地址空间中来使用

10.gcc -c main中的-c的意思是编译

C文件通过编译(预编译、编译、汇编)生成二进制可重定位文件,然后通过 链接生成二进制可执行文件

C文件到二进制可重定位文件是单文件进行,二进制可重定位文件到二进制可执行文件(链接的时候)是多文件进行

预编译:删除注释/* */ //等,处理#开头的预处理指令#include #define等,生成行号(如报错时提示的行号)和文件名索引

编译:生成符号,生成汇编码

汇编:将汇编码转成二进制,然后就生成了二进制可重定位文件

二进制可重定位文件(.o文件),Linux中 gcc -c生成.o文件 Linux中gcc -o 生成二进制可执行文件

编译是一个统称,包含了预编译,编译,汇编

链接:进行符号的重定位(单文件中很多的符号,多文件后有了更多的符号),然后生成二进制可执行文件,二进制可执行文件就可以直接执行了,然后放到虚拟地址空间中进行执行

###

二进制可重定位文件

1.二进制可重定位文件组成,在Linux系统,通过readelf -h main.o可以查看

在这里插入图片描述

Magic:前面四列(7f 45 4c 46)是魔数,用来标志一个文件

01:代表当前系统的位数 01:32为 10:64位 00:错误,有问题

01:大小端 01:大端 10:小端 00:错误

Class~Version:当前系统的信息

Entry point address:入口地址,如果显示0地址(0x0)说明这个文件执行的时候是从0地址执行,但是0地址到0x0804 8000是预留空间,是不可以访问的,所以说明当前文件是个不可以执行的文件,虽然是二进制文件,但是不可以执行

Start of program headers: program headers的开始位值 Start of program headers: 0(bytes into file)表示program headers的开始位值是从0x 00开始的

Start of section headers:section headers的开始位值 Start of section headers: 208(bytes into file)表示section headers的开始位值是从208(十六进制为0x d0)开始的

Size of this header: 52(bytes) 表示当前文件的头的大小为52字节(0x 34)

Size of section headers:40(bytes) 表示每块section headers的大小是40字节

Number of section headers: 9 表示section headers划分了9块

2.C文件经过编译生成二进制可重定位文件,然后经过链接生成二进制可执行文件,然后二进制可执行文件执行起来之后,会将数据放到虚拟地址空间中,然后经过地址映射,映射到内存中

3.off表示起始位置,size表示大小,al表示对齐方式

在这里插入图片描述

存储是按字节进行排列的,不可能出现重合的空间,但是为什么.bss段和.comment段的起始位置都是00005c(0x5c)呢?到底00005c(0x5c)是谁的起始地址呢?其实是.comment段的起始位置,而不是.bss段的,这是为什么呢?

.bss段只进行了标志,并没有给他真实的划分内存,.bss段存储的是没有初始化(没有初始化的值就是0)或者初始化为零的数据,就是说.bss段存储的都是零,不会产生数据值的修改,.bss段只用做到向下传递即可,当前文件并不是在执行空间里(不是二进制可执行文件而是二进制可重定位文件),只需要标志出来有这些东西就行

.symtab就是符号表,用来标记.bss段数据的存在

4. ①.bss段不进行真实的存储,那么如何标记这些数据的存在?

使用符号表进行标记

②.bss段大小为20字节,但是理论上存储在.bss段有六个int数据,应该是24字节,还有一个去哪里了?

还有一个并没有放在.bss段中,而是仅仅进行了一个COM标记,COM的含义是:弱符号,弱符号就是没有初始化的非静态数据,弱符号会在链接过程中被同名的强符号替代

5.什么是符号?所有的数据都会生成符号,函数名也会生成符号

在这里插入图片描述

6.指令一旦生成就不再改变了

7.为什么输出结果a为100,b为0?

因为fun中的a是一个弱符号,而右边文件中的a是一个强符号,在链接的时候,弱符号就会被同名的强符号替代,所以就会向右边文件的a的起始地址写入4个字节的100,因为右边文件a的大小为两个字节,所以又把b的值覆盖掉了,所以输出来的结果为0

这个程序在Linux系统中是可以执行的,在VS中有内存保护,写越界就会写入到保护的内存中去了,打印出来的b就还是20,在C++中同名会报错

在这里插入图片描述

二进制可执行文件

1.文件划分基本和二进制可重定位文件一样

在这里插入图片描述

2.在二进制可执行文件中,.bss段和.comment段的起始位置仍然是一样的

在这里插入图片描述

3.在二进制可执行文件中,data1现在在.bss段中存储(之前仅仅是COM标记),如果在链接过程中没有强符号的替换,那么就会把弱符号转换为强符号,链接之后就没有弱符号了,要么被强符号替代了,要么转换为强符号了

在这里插入图片描述

4.C文件仅仅编译后,fun函数和printf函数都属于未定义的状态,就是存在这个符号,但是具体引入到哪个地方还不知道,而main函数生成了指令,main函数所对应的位置在.text段中

在这里插入图片描述

5.在经过链接之后,fun函数所对应的位置在.text段中,但是为什么printf函数还是处在未定义的状态中呢?这是因为printf函数在动态库,只有执行的时候才会进行索引

在这里插入图片描述

6.动态库(.so或者.lib)

7.二进制可执行文件中各段的划分和大小

在这里插入图片描述

8.第一个load页是只读页,不可以修改的,常量;第二个load页是可读可写的

一个页是4K

在这里插入图片描述

9.虚拟地址空间:只是进行逻辑限定,执行起来后虚拟地址空间会映射到真实内存

10.真实存储:是在内存中

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: obs-studio的编译过程是将源代码转换为可执行文件的过程。对于obs-studio而言,它的编译过程涉及多个步骤。 首先,需要将编写的源代码保存为合适的文件格式,通常是使用C++语言进行开发。在编写代码时,需要考虑到obs-studio的特定要求和功能需求。 其次,在编译过程中,需要使用编译器来将源代码转换为机器语言。obs-studio常用的编译器包括GNU编译器集合(GCC)和Clang。编译过程中,编译器会检查代码中的语法错误和逻辑错误,并生成相应的目标文件。 然后,将生成的目标文件与必要的库文件进行链接。obs-studio依赖于许多外部库,如FFmpeg、libobs和libobs-scripting。链接过程的目的是将这些库文件与目标文件进行连接,形成完整的可执行文件。 最后,进行测试和调试。通过测试和调试,可以发现并解决代码中的错误和问题,确保obs-studio能够正常运行并拥有所需功能。 总结来说,obs-studio的编译过程包括保存源代码、使用编译器进行编译链接库文件以及进行测试和调试。这些步骤将源代码转换为可执行文件,使obs-studio能够顺利运行。 ### 回答2: obs-studio是一款开源的跨平台音视频录制和直播软件。下面将用300字中文回答obs-studio编译过程。 obs-studio的编译过程分为几个主要步骤: 1. 准备环境:首先需要安装相应的编译工具和依赖库。这些工具和库包括cmake、git、gcc等。安装完成后需要进行相关配置,如设置环境变量等。 2. 下载源代码:使用git从obs-studio的官方仓库下载最新的源代码。可以选择稳定版本或开发版,然后通过指定分支或标签来获取对应的代码。 3. 生成编译配置:使用cmake生成编译所需的配置文件。这些配置文件会指明编译器、依赖库路径、编译选项等。 4. 编译代码:运行指定的编译命令,如make或ninja。这将根据配置文件中的指示编译源代码,并生成对应的可执行文件。 5. 安装可执行文件:通过运行make install或ninja install命令,将编译生成的可执行文件和相关的资源文件复制到系统指定的目录中。 6. 设置环境:根据需要,可能需要进行一些环境的配置。比如,设置obs-studio的路径、输入输出设备的选择、直播平台的账号配置等。 综上所述,obs-studio的编译过程包括准备环境、下载源代码、生成配置、编译代码、安装可执行文件和设置环境等步骤。这样就能够成功地将obs-studio软件编译成可用的版本,以供音视频录制和直播等用途。 ### 回答3: OBS-Studio是一款开源的视频录制和直播软件,可以在Windows、Mac和Linux操作系统上使用。编译过程通常包括以下几个步骤: 1. 首先,需要准备编译所需的软件和工具。这包括安装C++编译器、CMake、Git和其他相关的库和依赖项。 2. 接下来,从OBS-Studio的官方GitHub页面上克隆或下载源代码。可以使用Git命令`git clone`或直接下载压缩文件。 3. 一旦源代码被获取,就可以开始配置编译环境。在命令行中导航到源代码的根目录,并执行CMake命令来生成Makefile文件。 4. 在生成的Makefile文件中,可以设置一些选项,如编译类型(Debug或Release)、安装目录等。 5. 确定好编译选项后,就可以运行Make命令进行编译了。这个过程可能需要一些时间,取决于计算机性能和源代码的规模。 6. 编译完成后,将生成可执行文件和相关的库文件。可以通过运行编译后的可执行文件来启动OBS-Studio。 总体来说,OBS-Studio的编译过程相对较简单,但需要一些基本的编译知识和工具的使用经验。通过正确配置编译环境,并按照编译流程进行操作,就可以成功地编译出OBS-Studio的可执行文件,并开始使用这款强大的视频录制和直播软件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值