一个简单的链接脚本,用来将两个以上的.o文件合并在一起,以及如何看机器码的含义

本文主要是介绍一个简单的链接脚本,用来将两个以上的.o文件合并在一起,以及如何看机器码的含义,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面是一个简单的lds链接脚本,用来将两个以上的.o文件合并在一起,并且用来指定链接后的代码加载到内存中的起始地址。

SECTIONS					@说明这是段的描述脚本
{. = 0xD0020010;		@加载代码到内存中的起始地址为0xD0020010.text : {			@代码段mystart.o	@mystart.o中的代码段放在最前面,因为mystart.o最前面是中断向量* (.text)	@其它.o文件代码段位置可以任意放置}.data : {			@数据段* (.data)	@*号说明各个.o文件的数据段位置无关}.bss_start = .;		@定义一个bss_start标号,可以给其它程序使用.bss : {			@未初始化数据段* (.bss)	@*号说明各个.o文件的数据段位置无关}.bss_end = .;		@定义一个bss_end标号,可以给其它程序使用
}

1.机器码如何看含义

首先我们使用arm-linux-objdump -S mystart.o查看一下mystart.o的机器码和汇编码:
ea000006是机器码,也就是最后会被添加到.bin文件中的代码; b 20 reset是汇编代码,这部分不会被添加最后的.bin文件中。
在这里插入图片描述
那么机器码如何看呢?
我们把ea000006展开为二进制,如下:
在这里插入图片描述
查看ARM手册:
在这里插入图片描述
可以知道cond=1110 op1=101,说明ea000006是一个Branch指令(意思就是PC相对跳转指令),我们跳转到手册的A5-212去看下。
在这里插入图片描述
在这里插入图片描述
对应的op是100000,我们跳转到ARM手册A8-332去看一下
在这里插入图片描述
以为我们用的是arm指令集,所以看Encoding A1.
imm32 = SignExtend(imm24:’00’, 32);这句说明要讲imm24后面添加两个00.也就是imm24 * 4.

ea000006的imm24是0x6, 也就是pc指针会在当前位置往前跳转0x6 * 4行。
Armv7是三级流水线,在执行ea000006这条指令是,pc指针中指向的是后面第三行指令ea000004,当执行完ea000006指令后pc加0x6*4行,指向eb000006. 同b 20 reset指令一样。这也就b 20 reset汇编指令的来源。
在这里插入图片描述
ea000006后面几条也都是这样解释的。
特别要说的是eaffffff这条。imm24: ffffff是-1的补码,执行完eafffffff后pc指针要从ffffffe调回到ea000006。

2.汇编后的代码

然讲下ebfffffe为何汇编为 bl 0 led2_on,跳转到0呢?那时因为led2_on没有在mystart.o中,编译器暂时用0代替。当包含led2_on函数的.o文件被链接后,这条指令会被重新编译。
在这里插入图片描述
led2_on函数在mylowlevel_init.o中,我们使用objdump查看一下:
在这里插入图片描述
然后使用我们最开始写的链接脚本将两个文件链接在一起,连接后的文件是 myboot.
从中我们可以看到bl 0 led2_on 已经被修改为bl d00200a0 led2_on. 同时也可以看到myboot的程序入库已经被修改为了0xD0020010了。

在这里插入图片描述
在这里插入图片描述

这篇关于一个简单的链接脚本,用来将两个以上的.o文件合并在一起,以及如何看机器码的含义的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/714987

相关文章

Oracle数据库定时备份脚本方式(Linux)

《Oracle数据库定时备份脚本方式(Linux)》文章介绍Oracle数据库自动备份方案,包含主机备份传输与备机解压导入流程,强调需提前全量删除原库数据避免报错,并需配置无密传输、定时任务及验证脚本... 目录说明主机脚本备机上自动导库脚本整个自动备份oracle数据库的过程(建议全程用root用户)总结

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Java中使用 @Builder 注解的简单示例

《Java中使用@Builder注解的简单示例》@Builder简化构建但存在复杂性,需配合其他注解,导致可变性、抽象类型处理难题,链式编程非最佳实践,适合长期对象,避免与@Data混用,改用@G... 目录一、案例二、不足之处大多数同学使用 @Builder 无非就是为了链式编程,然而 @Builder

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

利用Python脚本实现批量将图片转换为WebP格式

《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma