20240819编译 链接 单片机执行的第一个语句

2024年8月中旬在宝鸡出差,在B站上学习了下。

在linux操作系统中,gdb是调试器,gcc是编译器。

Linux 操作系统 将main.elf文件加载到内存中以后,操作系统为其分配进程,然后main函数就开始执行了。

输入 layout asm 则显示出来汇编代码 

键入 “starti”的时候 

进入到程序里面的第一个指令执行  发现程序进入的第一个指令 并不是main函数 而且是一个在库文件 Lib64/ld-linux-x86-64.so.2

这个start的地址是 0x7ffff7fe32b0 并不是mian 的首地址。 

然后在strat上再次打断点 

然后又进入了一个start里面

这个start 的地址是 0X555555555060  应该是程序自己的一个statrt 还没有进入到main 

然后在Main上打断点  。

 

用”ni”指令继续执行程序,程序调用了一个_GI_exit 实际上这个指令就是操作系统帮我们结束进程。 

20240818学习

进行预处理

 

进行编译成汇编 

 

可以看见下图 在Data 段落定义了字符传 hellow word   定义了main符号 是在代码段main 符号里面 都是X86汇编代码。

还发现: 

 

然后我还发现了作者是不是在 B站上写文章呢,也象知乎那样?

后来我发现是在博客园写的,写的比较好看

地址:编译?汇编?链接? - yudoge - 博客园 (cnblogs.com)

 

 

例如我们刚才看到的prinf 函数的调用 实际上CALL指令后面还是符号  目前不知道去哪里找这个 puts@PLT 这个东西 

 

实际上,打开预处理的源文件后 看见printf 也就是一个外部函数的申明,也没有函数体 

 

综上:所以单靠main一个文件是无法编译连接出可执行文件程序的。 还需要将printf在最后的可执行文件里面找到。

 

下一步:汇编main.s 通过编译编译变为可重定向的目标文件 main.o

可用 gcc命令做这个事情 

Gcc-c main.c  -o gcc main.o 

通过vim指令 可以看下 main.o 其实也看不了  因为已经是一个二进制文件 

 

但是可以使用 objdump 命令看下里面的代码信息 

 

 

通过上图可以看见 编译以后 Main函数还没有分配地址, 

 

 

 

通过上图 可以看见 e8 应该是call  call 后面也要跟地址,但是目前地址也是00 00 00 00

也不知从哪里去调用这个printf

 

我们可以通过-t 来看下符号表 如下图 

 

展开后的符号表 如下图所示 

 

通过下图可以看见 puts 符号是未定义的 

 

 

现在对目标文件进行链接的话, 可执行文件是执行不了的。

用 test  Ld main .o  - o main  发现如下图

如下图 提示有一个未定义的引用。 “puts”

那么符号“puts” 可能存在于另外一个目标文件.obj中,需要将另外一个目标文件也链接进来。 于是下一步 将两个目标文件obj ,链接到一个目标文件里面。 

2024年8月18日晚上

例如现在定义了两个C源文件  a.c 和 say.c

 

注意a.c文件中main()函数之前并没有包括头文件 #include“stdio.h“  于是在下面的图10中 会提示找不到 start 符号标识。 提示了警告 cannot find entry symbol _start; default   0x0000401000

 

a.c

Say.c

Void say()

Int main()

{

  Say();

}

Void say()

{

   int a = 10 ;

   while(1);

}

 

 

希望a.c文件中调用say()函数 

用gcc-c命令 生成目标文件

Gcc-c   a.c   -o   a.o

Gcc-c   say.c   -o  say.o

通过 objdump  -d   -t  a.o 来查看a.o 的目标链接文件。 如下图 

 

 

 

a.o 的目标链接文件如下图   实际下图的call函数 调用的是ssay函数 显然因为say函数没有在a.c函数中定义,所以 显示say函数是 UND   undefine 没有定义。

 

 

 

但是 say.o 中有这say这个符号的。 

 

 

 

于是可以把a.o 和 say.o 链接在仪器  输出一个a.out  

 

 

 

但是提示了 cannot find entry symbol _start; default   0x0000401000

因为:注意到a.c文件中main()函数之前并没有包括头文件 #include“stdio.h“  于是在下面的图10中 会提示找不到 start 符号标识。 提示了警告 cannot find entry symbol _start; default   0x0000401000   

 

通过以下命令 强制的指定main () 函数 作为入口地址  

Ld  -e main  a.o say.o  -o   a.out  “e” 表示的是entry  即入口地址 

 

 

 

通过上图中的  objdump  -d -t a.out   可以查看a.out 中的符号表 如下图 

 

 

 

 

 

可以看到 main 函数 和 say 函数的入口地址均已经指定了。 

 

然后 也看见 符号表 里面也没有  出现 UNDEF 地址了。 

 

 

 

于是 明白了链接的意义了, 即 不同文件里面的 可执行文件 .obj 合格成一个 可执行文件,把没有定义的符号,也定义了。

 

接下来我们回到问题, 操作系统执行的main 函数,操作系统结束了main 函数  

 

2024年8月22日先总结到这里

百度网盘链接

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/785644.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

回溯part02

今天继续学习了回溯:组合求和的进阶 元素可以重复使用:backtracking(candidates, target, sum, i); // 不用i+1了,表示可以重复读取当前的数 数组去重:首先数组排序,然后使用used 分割回文子串问题,抽象为组合问题,注意如何判断是否是回文子串5. 39 组合总和(元素可重复…

2.系统定时器

系统定时器SYSTEM文件夹介绍1,sys文件夹介绍sys_nvic_set_vector_table():设置中断向量表地址sys_intx_enable():开启所有中断sys_intx_disable():关闭所有中断(但是不包括fault和NMI中断)sys_wfi_set():执行: WFI指令(执行完该指令进入低功耗状态)sys_standby():进入待机…

Terraform - 初解Terraform - 安装

开发环境配置 Note:安装环境为windows系统64位笔记本电脑 1.安装适用于 Windows 的 Terraform: https://developer.hashicorp.com/terraform/install 2.下载 Terraform: https://releases.hashicorp.com/terraform/1.9.4/terraform_1.9.4_windows_amd64.zip 3.从下载中,将…

python 05-标准库:csv、json、sqlite3、datetime模块

csv模块import csv# data.csv不存在时,会现在当前目录下创建一个data.csv文件 with open("data.csv", "w", encoding=utf-8) as file:writer = csv.writer(file)writer.writerow(["trasanction_id", "product_id", "price_id&qu…

初识方法

1.方法是什么 1.java方法是语句的合集,放在一起执行一个功能。 2.方法包含于类或对象中 3.方法在程序中被创建,在其他地方被引用 2.方法的原则:原子性 一个方法只能完成一个功能 3.在main方法外计算 1.先在main外面书写一个加法方法2.再在main里面直接输出加法方法总览:

Terraform - 初解Terraform - 简介

前言 云计算 主要提供计算服务,例如服务器、存储、数据库、网络等等; 对于云服务,通常只需使用多少支付多少,从而帮助降低运营成本,使基础设施更有效地运行,并能根据业务需求的变化调整对服务的使用。公有云: 多租户面向个人或企业由第三方云服务商托管和运营。 私有云: …

045、Vue3+TypeScript基础,pinia库中使用$subscribe订阅数据变动

01、main.js代码如下:// 引入createApp用于创建Vue实例 import {createApp} from vue // 引入App.vue根组件 import App from ./App.vue//第一步:引入pinia import {createPinia} from piniaconst app = createApp(App);//第二步:创建pinia实例 const pinia = createPinia()…

爬虫案例1-爬取图片的三种方式之一:DrissionPage篇(3)

继requests篇和selenium篇,本文是爬取图片的最后一个案例,利用了python第三方库DrissionPage来自动化爬取图片。当然,爬取图片肯定不止这三种方法,还有基于python的scrapy框架,基于node.js的express框架以及基于Java的webmagic框架等等。 DrissionPage和selenium相似,都是…

HtmlUnit:自动化操作web页面的java工具

java有httpclient等工具,可以模拟进行一些web操作,但一些逻辑是在前端js中执行的,此时httpclient就比较困难了。 此时可以考虑使用HtmlUnit,模拟出一个浏览器,全程在浏览器中操作。本文以 在百度中输入搜索关键字->点击“百度一下” 按钮->打印搜索结果 这一过程为例…

nginx代理服务

Nginx****代理服务代理区别 区别在于代理的对象不⼀样 正向代理代理的对象是客户端 反向代理代理的对象是服务端 2.Nginx****负载均衡2.2Nginx****负载均衡状态配置 backup max_conns 测试 backup 以及 down 状态 当⼀个后端服务器被标记为 backup 时,它将仅作为备⽤服务器使⽤…

声音克隆GPT-SoVITS 2.0软件和详细的使用教程!

天命人,请允许我先蹭个热点! 原始声音: 播放 克隆声音: 播放 文章写了一半,被《黑神话悟空》刷屏了。突发奇想,用里面的声音来做个素材试试看。B站捞了一点声音素材,随便剪一剪,训练一把过,没有调优,就直接拿来用了。情绪还差点意思,音色克隆的还不错。 下面进入正…

手机轰炸机 短信轰炸 可匣 二90二1243交流

使用 fiddler 抓包 获取到了 100+个 发送短信验证的接口 使用自己手机试了一下 速度非常快。因为是同时迸发,所以导致手机短信量一瞬间到了100+ 但是会导致一个问题,就是无感知情况 于是调整接口请求方式,设置异步请求,间隔3s钟,这次以后会达到一个比较好的效果 没办法上传…