arm 交叉编译 thumb 与 arm 指令的方法

arm 交叉编译 thumb 与 arm 指令的方法

  • 本文实现了在 x86 的 ubuntu 的机器上,使用 arm-linux-gnueabihf-gcc 交叉编译链工具,编译出在 arm 开发板上可以运行的 thumb 指令集的可执行文件。后续会使用 vscode 使用网络进行远程调试。

1. 编译器 arm-linux-gnueabihf-gcc

# arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/11/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --without-target-system-zlib --enable-multiarch --disable-sjlj-exceptions --with-arch=armv7-a+fp --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- --includedir=/usr/arm-linux-gnueabihf/include --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) 

ubuntu 中安装方法 sudo apt-get install binutils-arm-linux-gnueabi gcc-arm-linux-gnuabihf

2. 代码中实现

使用 __attribute__((target("thumb"))) void thumb_ins(void); 指定函数编译为 thumb 指令

//完整的 main.c 的示例
#include <stdio.h>

__attribute__((target("thumb"))) void thumb_ins(void);
void thumb_ins(void) {
	int ia = 0;
	int ib = 0;
	int ic = 0;

	while (1) {
		ia = 0;
		ib = 0;
		ic = 0xab;

		asm volatile ("mov r0, #1");
		asm volatile ("mov r4, #0");
		asm volatile ("cmp r4, #0");
		asm volatile ("itte  eq");
		asm volatile ("moveq r1, #55");
		asm volatile ("moveq r2, #66");
		asm volatile ("movne r2, #77");

		asm volatile ("mov %0, r1" : "=r" (ia));
		asm volatile ("mov %0, r2" : "=r" (ib));
		asm volatile ("mov %0, r0" : "=r" (ic));

		if ((ia != 55) || (ib != 66)) {
			printf("error!!!");
			printf(" ia %d ib %d  %d\r\n", ia, ib, ic);
		}
	}
}

int main(void)
{
  printf("I run!!! %s %s\r\n", __TIME__, __DATE__);

  while (1) {
    thumb_ins();
  }

  return 0;
}

3. 编译方法

  • 编译指令 arm-linux-gnueabihf-gcc -g -static -mthumb-interwork -mthumb main.c

    参数解释:

    -g 添加调试信息

    -static 使用静态链接的方式

    -mthumb 使用 thumb 指令集

    -mthumb-interwork 支持 arm 与 thumb 混合

  • 反汇编查看是否正确 arm-linux-gnueabihf-objdump -S a.out > a.asm

__attribute__((target("thumb"))) void thumb_ins(void);
void thumb_ins(void) {
   10438:	b580      	push	{r7, lr}
   1043a:	b084      	sub	sp, #16
   1043c:	af00      	add	r7, sp, #0
	int ia = 0;
   1043e:	2300      	movs	r3, #0
   10440:	607b      	str	r3, [r7, #4]
	int ib = 0;
   10442:	2300      	movs	r3, #0
   10444:	60bb      	str	r3, [r7, #8]
	int ic = 0;
   10446:	2300      	movs	r3, #0
   10448:	60fb      	str	r3, [r7, #12]

	while (1) {
		ia = 0;
   1044a:	2300      	movs	r3, #0
   1044c:	607b      	str	r3, [r7, #4]
		ib = 0;
   1044e:	2300      	movs	r3, #0
   10450:	60bb      	str	r3, [r7, #8]
		ic = 0xab;
   10452:	23ab      	movs	r3, #171	; 0xab
   10454:	60fb      	str	r3, [r7, #12]

		asm volatile ("mov r0, #1");
   10456:	f04f 0001 	mov.w	r0, #1
		asm volatile ("mov r4, #0");
   1045a:	f04f 0400 	mov.w	r4, #0
		asm volatile ("cmp r4, #0");
   1045e:	2c00      	cmp	r4, #0
		asm volatile ("itte  eq");
   10460:	bf06      	itte	eq
		asm volatile ("moveq r1, #55");
   10462:	2137      	moveq	r1, #55	; 0x37
		asm volatile ("moveq r2, #66");
   10464:	2242      	moveq	r2, #66	; 0x42
		asm volatile ("movne r2, #77");
   10466:	224d      	movne	r2, #77	; 0x4d

		asm volatile ("mov %0, r1" : "=r" (ia));
   10468:	460b      	mov	r3, r1
   1046a:	607b      	str	r3, [r7, #4]
		asm volatile ("mov %0, r2" : "=r" (ib));
   1046c:	4613      	mov	r3, r2
   1046e:	60bb      	str	r3, [r7, #8]
		asm volatile ("mov %0, r0" : "=r" (ic));
   10470:	4603      	mov	r3, r0
   10472:	60fb      	str	r3, [r7, #12]

		if ((ia != 55) || (ib != 66)) {
   10474:	687b      	ldr	r3, [r7, #4]
   10476:	2b37      	cmp	r3, #55	; 0x37
   10478:	d102      	bne.n	10480 <thumb_ins+0x48>
   1047a:	68bb      	ldr	r3, [r7, #8]
   1047c:	2b42      	cmp	r3, #66	; 0x42
   1047e:	d0e4      	beq.n	1044a <thumb_ins+0x12>
			printf("error!!!");
   10480:	4b06      	ldr	r3, [pc, #24]	; (1049c <thumb_ins+0x64>)
   10482:	447b      	add	r3, pc
   10484:	4618      	mov	r0, r3
   10486:	f004 fb67 	bl	14b58 <_IO_printf>
			printf(" ia %d ib %d  %d\r\n", ia, ib, ic);
   1048a:	68fb      	ldr	r3, [r7, #12]
   1048c:	68ba      	ldr	r2, [r7, #8]
   1048e:	6879      	ldr	r1, [r7, #4]
   10490:	4803      	ldr	r0, [pc, #12]	; (104a0 <thumb_ins+0x68>)
   10492:	4478      	add	r0, pc
   10494:	f004 fb60 	bl	14b58 <_IO_printf>
		ia = 0;
   10498:	e7d7      	b.n	1044a <thumb_ins+0x12>
   1049a:	bf00      	nop
   1049c:	0003f1be 	.word	0x0003f1be
   104a0:	0003f1ba 	.word	0x0003f1ba

000104a4 <main>:
	}
}

最后将 a.out 放入目标板卡使用 chmod +x 添加执行权限,即可运行。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day19 代码随想录打卡|字符串篇---反转字符串II

题目&#xff08;leecode T541&#xff09;&#xff1a; 给定一个字符串 s 和一个整数 k&#xff0c;从字符串开头算起&#xff0c;每计数至 2k 个字符&#xff0c;就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个&#xff0c;则将剩余字符全部反转。如果剩余字符小…

OceanBase 轻量级数仓关键技术解读

码到三十五 &#xff1a; 个人主页 为了更好地聚合和治理跨域数据&#xff0c;帮助企业用较低的成本快速聚合分析&#xff0c;快速决策&#xff0c;不断的让企业积累的数据产生价值&#xff0c;从全域海量数据抓取&#xff0c;高性能流批处理&#xff0c;元数据血缘治理等等方面…

数据分析从入门到精通 1.numpy 剑客修炼

会在某一瞬间突然明白&#xff0c;有些牢笼是自己给自己的 —— 24.5.5 一、数据分析秘笈介绍 1.什么是数据分析 是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来&#xff0c;总结出所研究对象的内在规律。使得数据的价值最大化 案例&#xff1a; 分析用户的消…

Kotlin: Expecting a ‘>‘

数组值为任意类型&#xff0c;声明报错: Kotlin: Expecting a > var anyArr1: Array<Any?> arrayOf("a", "b", "c", true, 34)原因是&#xff1a; // var anyArr1: Array<Any?> arrayOf("a", "b", "c…

概念解析 | 威胁建模与DREAD评估:构建安全的系统防线

注1:本文系"概念解析"系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:威胁建模和DREAD模型 概念解析 | 威胁建模与DREAD评估:构建安全的系统防线 What Is Threat Modeling? Definition, Process, Examples, and Best Practices - Spic…

蓝桥杯-路径之谜

题目描述 小明冒充X星球的骑士&#xff0c;进入了一个奇怪的城堡。城堡里面什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡的地面时n*n个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或者纵向移动&#xff0c;但是不能斜着走&#x…

SpringBoot自定义定时任务

通常&#xff0c;在我们的项目中需要定时给前台发送一些提示性消息或者我们想要的定时信息&#xff0c;这个时候就需要使用定时任务来实现这一功能&#xff0c;实现也很简单&#xff0c;接下来具体来看看吧~ 简单定时任务 首先&#xff0c;你需要在你的启动类上加上开启定时任…

贪吃蛇(下)游戏的实现

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 文章目录 前言一.蛇和食物的打印二.游戏的运行逻辑三.结束游戏 &#xff08;善后工作&#xff09;四.游戏的测…

K8S-Dashboard安装并创建普通用户

参考&#xff1a;在centos stream 9上搭建k8s最新版本&#xff08;当前&#xff1a;v1.26.1&#xff09;集群环境 查找dashboard 对应的版本 https://github.com/kubernetes/dashboard/releases 下载 kubernetes-dashboard.yaml 使用的2.7.0 wget https://raw.githubuserconte…

mac安装虚拟机linux系统

需要下载的有&#xff1a;centos8镜像 , 虚拟器 VMware 软件包 , Termius 或者xshell 1. CentOS系统下载 linux系统一般有&#xff1a; CentOS、ubuntu、redhat&#xff0c;选择一种进行安装就可以 CentOS 2024 年开始停止维护和发布 CentOS8的下载与安装(windows下安装) 镜…

【网络安全产品】---应用防火墙(WAF)

what Web应用防火墙&#xff08;Web Application Firewall) WAF可对网站或者App的业务流量进行恶意特征识别及防护&#xff0c;在对流量清洗和过滤后&#xff0c;将正常、安全的流量返回给服务器&#xff0c;避免网站服务器被恶意入侵导致性能异常等问题&#xff0c;从而保障…

3.10设计模式——Template Method 模版方法模式(行为型)

意图 定义一个操作中的算法骨架&#xff0c;而将一些步骤延迟到子类中&#xff0c;Template Method 使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。 结构 AbstractClass&#xff08;抽象类&#xff09;定义抽象的原语操作&#xff0c;具体的子类将重定…

C++:set和map的介绍

目录 关联式容器 键值对 set介绍&#xff1a; set的模板参数列表 set的双向迭代器&#xff1a; insert的使用和set的特性&#xff1a; set的删除&#xff1a; set的find&#xff1a; lower_bound 、 upper_bound&#xff1a; multiset&#xff1a; map介绍&#xff…

C语言——指针的奥秘(1.0)

指针 一.内存和地址1.内存2.编址 二.指针变量和指针1.取地址操作符&#xff08;&&#xff09;2.指针变量和解引用操作符&#xff08;*&#xff09;1.指针变量2.拆解指针类型3.解引用操作符4.指针变量的大小 三.指针变量的类型和意义1.指针的解引用2.指针 - 整数3.void* 指针…

JVM笔记1--Java内存区域

1、运行时数据区域 从上图可以看出来&#xff0c;Java虚拟机运行时数据区域整体上可以分成5大块&#xff1a; 1.1、程序计数器 程序计数器是一块较小的内存空间。它可以看做当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里&#xff0c;字节码解释器工作时就是…

OpenAI下周将发布ChatGPT搜索引擎,挑战谷歌搜索!

目前&#xff0c;多方位消息证实&#xff0c;OpenAI将会在5月9日上午10点公布该消息&#xff0c;大约是北京时间周五的凌晨2点。 5月3日&#xff0c;前Mila研究员、麻省理工讲师Lior S爆料&#xff0c;根据OpenAI最新的SSL证书日志显示&#xff0c;已经创建了search.chatgpt.c…

Java集合排序

1. 集合排序API 1.1 集合排序概述 集合排序是指对一个集合中的元素按照特定规则进行重新排列&#xff0c;以使得集合中的元素按照预定义的顺序呈现。 在集合排序中&#xff0c;通常需要定义一个比较规则&#xff0c;这个比较规则用于决定集合中的元素在排序后的顺序。元素之间…

KIE基于图模型的关键信息抽取源码详解

1.数据集准备 下载数据集 https://download.openmmlab.com/mmocr/data/wildreceipt.tar WildReceiptOpenset 准备好 WildReceipt。 转换 WildReceipt 成 OpenSet 格式: # 你可以运行以下命令以获取更多可用参数: # python tools/dataset_converters/kie/closeset_to_opens…

程序的机器级表示——Intel x86 汇编讲解

往期地址&#xff1a; 操作系统系列一 —— 操作系统概述操作系统系列二 —— 进程操作系统系列三 —— 编译与链接关系操作系统系列四 —— 栈与函数调用关系操作系统系列五 —— 目标文件详解操作系统系列六 —— 详细解释【静态链接】操作系统系列七 —— 装载操作系统系列…

java下乡扶贫志愿者招募管理系统springboot-vue

计算机技术在现代管理中的应用&#xff0c;使计算机成为人们应用现代技术的重要工具。能够有效的解决获取信息便捷化、全面化的问题&#xff0c;提高效率。 技术栈 前端&#xff1a;vue.jsElementUI 开发工具&#xff1a;IDEA 或者eclipse都支持 编程语言: java 框架&#xff1…
最新文章