ARM 汇编语言基础
目录
汇编指令代码框架
汇编指令语法格式
数据处理指令
数据搬移指令 mov
示例
立即数的本质
立即数的特点
立即数的使用
算术运算指令
指令格式
add 普通的加法指令
adc 带进位的加法指令
跳转指令
Load/Store指令
状态寄存器指令
基础概念
-
C 语言与汇编指令的关系
- 语句:带有分号 (
;
) 的 C 语言语句可以被编译成汇编指令。 - 预处理指令:以井号 (
#
) 开头的行称为预处理指令,它们告诉编译器如何处理源代码。
- 语句:带有分号 (
-
汇编语言的整体分类
- 指令:编译后生成一条机器码,存储在内存中供 CPU 执行。
- 伪操作:不生成机器码也不占用内存,用于控制汇编过程。
(相当于c中的’#‘的内容)告诉编译器怎么编译)
- 伪指令:在编译时被替换为一系列等效的指令,用于实现某些高级功能。
(如:cpu中没有乘法器,对应没有乘法指令,3*3 ---》用加法器实现3+3+3,替换实现)
-
注释
- 单行注释:使用
@
符号开始。 - 多行注释:使用
/**/
包围。
- 单行注释:使用
-
指令分类
- 数据处理指令:对数据进行逻辑和算术运算。
- 跳转指令:改变程序流程,即修改程序计数器 PC。
- Load/Store 指令:读取和写入内存。
- 状态寄存器传送指令:读写 CPSR(当前程序状态寄存器)。
- 异常中断产生指令:触发软件中断(SWI),用于系统调用。
- 协处理器指令:操作协处理器,比如浮点运算单元 FPU。
汇编指令代码框架
.text
.global _start
_start:; 汇编代码段
.end
汇编指令语法格式
<opcode><code>{s} Rd, Rn, operand2
- opcode:指令名称。
- code:条件码,可选,默认无条件执行。
- s:是否更新 CPSR 的标志位。
- Rd:目标寄存器。
- Rn:第一个操作寄存器。
- operand2:第二个操作数,可以是寄存器或立即数。
- 注:指令的名字,条件码,s连到一起写,指令名和目标寄存器之间使用空格,寄存器和数据之间使用逗号隔开,指令中的字符不区分大小写
数据处理指令
数据搬移指令 mov
- 格式:
<opcode><code>{s} Rd, operand2
- 立即数形式:
mov{<code>}{s} Rd, #immediate
示例
在这个示例中,我们首先声明了一个 .text
段,然后定义了一个全局符号 _start
,这是程序的入口点。接下来我们初始化寄存器 R0
为 0x1234
,然后将 R0
的值复制给 R1
。最后,通过 bx lr
返回到调用者
.text
.global _start_start:; 初始化寄存器 R0 为 0x1234mov r0, #0x1234; 将 R0 的值移动到 R1mov r1, r0; 结束程序bx lr.end
- 1》数据搬移指令 mov
- @ 格式:<opcode><code>{s} Rd, oprand2
- 如果是立即数,前边必须加#
PC寄存器详细讲解:
指令的执行三步:取指,译码,执行(PC永远指向当前正在取指指令的地址)。
立即数在 ARM 汇编语言中是一个重要的概念。立即数是直接编码在指令中的数值,它与普通变量不同,后者通常存储在内存中。下面是关于立即数的一些详细说明和优化后的格式:
立即数的本质
立即数是直接嵌入在指令中的数据,作为指令的一部分。这意味着当指令被加载到处理器中时,立即数也会同时被加载。
立即数的特点
- 优点:
- 快速访问:因为立即数是与指令一同加载的,所以不需要额外的时间去内存中获取。
- 节省空间:如果立即数足够小,那么可以减少对寄存器的需求,从而节省空间。
- 缺点:
- 数量有限:立即数的大小受到指令格式的限制,ARM 架构中立即数通常被限制在一定范围内。
- 表达能力受限:由于立即数大小的限制,有时候无法直接表示较大的数值。
立即数的使用
在 ARM 汇编语言中,立即数通常用于简单的数值操作,例如赋值或者与寄存器进行逻辑运算。立即数只能是某些特定的值,并且这些值通常被限制为可以由指令直接处理的形式。
如:MOV ,#0x12345678 @报错,不合法
0x1234
是一个有效的立即数,因为它可以通过位移得到。但是 0x12345678
则不是一个有效的立即数,因为它超过了 8 位的限制,并且不能通过简单的位移得到。 注:使用mov 给寄存器里面存放值的时候,#号后面需是有效数(1:立即数,2:取反之后是立即数),如果不是立即数需要用ldr指令进行存放。
算术运算指令
常见的算术运算指令包括:
- add:加法
- adc:带进位的加法
- sub:减法
- sbc:带借位的减法
- mul:乘法
指令格式
算术运算指令的一般格式如下:
<opcode>{<code>}{s} Rd, Rn, operand2
其中:
<opcode>
是指令名称。<code>
是条件码,可选。{s}
表示是否更新 CPSR 的标志位。Rd
是目标寄存器。Rn
是第一个操作寄存器。operand2
是第二个操作数,可以是寄存器或立即数。
add 普通的加法指令
adc 带进位的加法指令
假设2个64位的数相加
- 第一个64位的数,R0存放低32位,R1存放高32位,
- 第二个64位的数,R2存放低32位,R3存放高32位
- 结果R4存放低32位,R5存放高32位
add和ADC的区别,例如是64位的字符,如果低位大小满足进1的话用ADD只会显示在C进1,但是存储的地址并不进1,ADC的话则会将存储的地址进1
注意:mul r2, r0, #0x4 @ 错误
乘法指令的第二个操作数只能是一个寄存器
mul r2, r1,r0
跳转指令
1》修改PC,不建议使用,因为需要查询指令的地址
2》 b bl :指令跳转
- 格式:b/bl Label
- Label: 指令
- 相当C语言的函数调用
- B指令(不带返回的跳转)
不保存返回地址的跳转(返回地址不保存到lr中)
- BL指令(带返回的跳转指令),将LR的值修改成跳转指令下一条指令的地址,再将PC的值修改成跳转标识符下指令的地址
补充了解:
RM指令条件码表:可跟的判断条件成立跳转(NZCV在用于判断两者之间关系使用比较多)
如:c代码如下:
练习:
实现以下逻辑unsigned int r1 = 9;unsigned int r2 = 15;while(1){if(r1 == r2)goto stop;if(r1 > r2)
r1 = r1 - r2;if(r1 < r2)
r2 = r2 - r1;}
stop:while(1);汇编指令练习答案如下:
mov r1,#9
mov r2,#15
loop:
cmp r1,r2 @cmp 比较指令
beq stop
subhi r1,r1,r2
subcc r2,r2,r1
b loop
stop:
b stop
Load/Store指令
对内存的读写操作//如 a++ 读a的值,将运算结果从cpu写道内存
可用地址查找:(我们不用查找,脚本文件中配置了内存空间的分配) 查看内存中内容:
1>单寄存器操作指令 ldr/str
- 格式:ldr/str Rm, [Rn]
- Rm: 存储是数据
Rn:存储的数据,地址
将CPU中r1寄存器中的数据存储到内存中r0地址的空间中
- 将r0指向的地址空间中的内容,读到r2寄存器中
- ldr r2, [r0]
- 将r1中的值存储到r0+4指向的地址空间中,R0中的值不变
- str r1, [r0, #4];
- 将r2中的值存储到r0指向的地址空间中,r0 = r0 + 4
- str r2, [r0], #4
- 将R3中的值存储到R0+4指向的地址空间中,并且r0 = r0 + 4
- str r3, [r0, #4]!
- 2>多寄存器操作指令 stm ldm
- 将r1到r4中的值存储到r0指向地址空间中,连续16个字节的地址空间
- stm r0, {r1-r4}
- 将r0指向的地址空间中,连续的16个字节的数据,读到r5-r8寄存器中
- ldm r0, {r5-r8}
- 如果寄存器列表中的寄存器编号既有连续又有不连续,连续的使用“-”隔开,不连续的使用“,”
- stm r0, {r1-r3,r4}
- 2. 不管寄存器列表中的寄存器编号顺序如何变化,都是小地址对应小编号的寄存器高地址对应大编号的寄存器
- stm r0, {r4,r3,r2,r1}
- ldm r0, {r8,r7,r6,r5}
- 3>栈的操作指令 stmfd ldmfd
- 栈的种类
- 空栈(Empty)
栈指针指向的地址是空的,在栈中存储数据时,可以直接存储,存储完成之后需要将栈指针再次指向空的位置。
- 满栈(Full)
栈指针指向的地址有数据,在栈中存储数据时,需要先将栈指针,指向一个空的位置,然后在存储数据。
- 增栈(Ascending)
栈指针向高地址方向移动
- 减栈(Descending)
栈指针向低地址方向移动
操作栈的方式有四种
- 满增栈 满减栈 空增栈 空减栈
- FA:Full Ascending 满增(FA)
- FD:Full Descending 满减(FD)
- EA:Empty Ascending 空增(EA)
- ED:空减
- ARM默认采用的是满减栈
- stmfd/ldmfd<code> sp!, {寄存器列表}
- stmfd sp!, {r1-r5}(写) (压栈)
更新栈指针指向的地址空间
- ldmfd sp!, {r6-r10}(读) (出栈)
特殊:
stmfd sp!, {r1-r5,lr}(写) (压栈)
ldmfd sp!, {r6-r10,pc}(读) (出栈) //r1-r5出栈给r6-r10, 将lr的值出栈给pc
状态寄存器指令
对CPSR进行读写操作//其他都不能动CPSR (SWI 指令是linux内核有,所以arm为了匹配才有的指令)(CPSR保存cpu的状态、模式、中断中断开关、运算状态,非常重要,不能任意更改,只有一类指令能操作这个寄存器)
1》读cpsr 指令mrs
2》写cpsr 指令 msr :一般情况不能修改cpsr,只能用msr命令修改,user模式下不能切换到其他模式。
注:修改CPSR的控制域(bit[7:0]),修改CPSR时必须指定修改哪个区域
USER模式下不能修改CPSR的值,防止应用程序修改CPU状态,保护操作系统
CPSR_C修改的是CPSR的低八位ctrl(控制)域,一般都只修改C域
OK,就分享到这,如果帮到你那就点个关注吧~
相关文章:

ARM 汇编语言基础
目录 汇编指令代码框架 汇编指令语法格式 数据处理指令 数据搬移指令 mov 示例 立即数的本质 立即数的特点 立即数的使用 算术运算指令 指令格式 add 普通的加法指令 adc 带进位的加法指令 跳转指令 Load/Store指令 状态寄存器指令 基础概念 C 语言与汇编指令的关…...

c语言小知识点小计
c语言小知识点小计 1、运算符的优先级 运算符的优先级是和指针解引用*的优先级相同的,但在代码运行中执行顺序是从后往前的。因此下面代码 int a[10] {1,2,3,4}; int* arr a; printf("%d",*arr);//访问的值是2 //注意:printf("%d&qu…...

《C#面向语言版本编程》C# 13 中的新增功能
将C#语言版本升级为预览版 C# 13 包括一些新增功能。 可以使用最新的 Visual Studio 2022 版本或 .NET 9 预览版 SDK 尝试这些功能。若想在.NET项目中尝试使用C#的最新预览版特性,可以按照以下步骤来升级你的项目语言版本: .打开项目文件: 找…...

0成本通过Hugo和GitHub Pages搭建博客
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 使用 Chocolatey 安装 Hugo Chocolatey 是一个 Windows 软件包管理器,使用 PowerShell 和 NuGet 作为基础。它可以自动化软件的安装、升级和卸载过…...

Ollama 可以玩 GLM4和CodeGeeX4了
最近这一两周看到不少互联网公司都已经开始秋招提前批了。 不同以往的是,当前职场环境已不再是那个双向奔赴时代了。求职者在变多,HC 在变少,岗位要求还更高了。 最近,我们又陆续整理了很多大厂的面试题,帮助一些球友…...

浅析C++指针与引用的关系
前言: 在实践中指针与引用相辅相成,功能相互叠加,但各有各的特点,互相不可替代!!!...

Python面试宝典第31题:字符串反转
题目 编写一个函数,其作用是将输入的字符串反转过来,输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组,并使用O(1)的额外空间解决这一问题。备注:s[i]都是ASCII码表中的可打印…...

【深入理解SpringCloud微服务】深入理解微服务中的远程调用,并手写一个微服务RPC框架
【深入理解SpringCloud微服务】深入理解微服务中的远程调用,并手写一个微服务RPC框架 远程过程调用微服务中的RPC框架如何实现一个微服务中的RPC框架接口扫描生成代理对象代理对象处理逻辑 手写一个微服务RPC框架RPCClientEnableRPCClientMicroServiceRPCClientRegi…...

数据结构----二叉树
小编会一直更新数据结构相关方面的知识,使用的语言是Java,但是其中的逻辑和思路并不影响,如果感兴趣可以关注合集。 希望大家看完之后可以自己去手敲实现一遍,同时在最后我也列出一些基本和经典的题目,可以尝试做一下。…...

通过python管理mysql
打开防火墙端口: 使用 firewall-cmd 命令在防火墙的 public 区域中永久添加 TCP 端口 7500(FRP 控制台面板端口)、7000(FRP 服务端端口)以及端口范围 6000-6100(一组客户端端口)。这些端口是 FR…...

Run the OnlyOffice Java Spring demo project in local
Content 1.Download the sample project in java2.Run the project3.Test the example document 1.Download the sample project in java Link: download the sample code in official website document properties setting spring 项目所在的服务器 server. Address192.168…...

11. Rancher2.X部署多案例镜像
**部署springboot项目 : ** **部署中间件Mysql8.0 : ** 名称:service-mysql 端口 :3306:3306 镜像:mysql:8.0 环境变量: MYSQL_ROOT_PASSWORDxdclass.net168路径映射 /home/data/mysql/data /var/lib/mysql:rw /etc/localtime…...

探索Linux世界之Linux环境开发工具的使用
目录 一、yum -- Linux软件包管理器 1、什么是yum 2、yum的使用 2.1 yum一些经常见的操作 1.查看软件包 2. 安装软件包 3. 删除软件包 3、yum的周边知识 3.1 yum的软件包都是从哪里来的?是从哪里能下载到这些软件包? 3.2 yum的拓展软件源 二、…...

探索Spring Boot微服务架构的最佳实践
目录 引言 一、Spring Boot简介 二、微服务架构的关键要素 三、Spring Boot在微服务中的最佳实践 3.1 清晰的服务边界 3.2 自动化配置与依赖管理 3.3 服务注册与发现 3.4 配置管理 3.5 安全与认证 3.6 监控与日志 3.7 分布式事务 四、总结 引言 在当今快速迭代的软…...

[论文泛读]zkLLM: Zero Knowledge Proofs for Large Language models
文章目录 介绍实验数据实验数据1实验数据2实验数据3 介绍 这篇文章发在CCS2024,CCS是密码学领域的顶会。作者是来自加拿大的University of Waterloo。文章对大语言模型像GPT和LLM等大语言模型实现了零知识可验证执行,但不涉及零知识可验证训练。个人觉得…...

vscode插件中的图标怎么设置
首先在ts文件目录下和package.json同级的目录下加入一张图片,后缀是jpg、png、jpeg都可以。 然后package.json中加入该行 重新 vsce package即可 如果出现报错 The specified icon xxx/xxx/icon.jpg wasnt found in the extension. 那就是没有放正确文件夹的位…...

Study--Oracle-08-oracle数据库的闪回技术
一、闪回恢复区(Flash Recovery Area) 1、什么是闪回恢复区 闪回恢复区是Oracle数据库中的一个特殊存储区域,用于集中存放备份和恢复数据库所需的所有文件,包括归档日志和闪回日志。这个区域可以帮助数据库在遇到介质故障时进行完全恢复。通过将备份数…...

获取客户端真实IP
出于安全考虑,近期在处理一个记录用户真实IP的需求。本来以为很简单,后来发现没有本来以为的简单。这里主要备忘下,如果服务器处于端口回流(hairpin NAT),keepalived,nginx之后,如何取得客户端的…...

韩式告白土味情话-柯桥生活韩语学习零基础入门教学
你们韩国人别太会告白了! 1、너 얼굴에 뭐가 조금 묻었어! 你的脸上有点5376东西! 뭐가 조금 묻었1585757는데? 有点什么? 이쁨이 조금 묻었네. 有点漂亮。 2、돌잡이 때 뭐 잡았어요? 你抓周的时候抓了什么? 쌀 잡았…...

Linux安全与高级应用(一)深入探讨Linux安全与高级应用
文章目录 深入探讨Linux安全与高级应用引言目录一、Linux安全与应用概述1.1 Linux的应用现状1.2 Linux的安全需求 二、构建LAMP企业网站平台2.1 LAMP平台简介2.2 安装和配置Apache服务器2.2.1 安装Apache2.2.2 配置Apache 2.3 安装和管理MySQL数据库2.3.1 安装MySQL2.3.2 配置M…...

【nginx 第二篇章】各个环境安装 nginx
一、Windows环境安装 1、下载 Nginx 访问Nginx官网(http://nginx.org/en/download.html)下载稳定版本的 Nginx 压缩包,如 nginx-1.xx.x.zip。下载后解压到指定的目录,例如 D:\nginx。 2、启动 Nginx 直接双击解压目录下的 ngi…...

在Spring Boot和MyBatis-Plus项目中,常见的错误及其解决方法2.0
1. org.springframework.beans.factory.BeanCreationException: Error creating bean with name requestMappingHandlerMapping 现象 在创建bean时发生错误,通常是因为存在重复的URL映射。 解决方法 检查所有控制器方法上的URL映射注解,确保没有重复…...

招聘信息数据清洗
文章目录 前言代码示例如下 前言 相关知识 为了完成本关任务,你需要掌握: 1.Spark 清洗数据的相关方法, 2.空值列怎么删除; 3.怎么数据切分才能达到想要的数据。 Spark清洗数据相关方法 一、将含有空值的数据删除 1.将含有空值的数据删除&a…...

机器学习——支持向量机(SVM)(1)
目录 一、认识SVM 1. 基本介绍 2. 支持向量机分类器目标 二、线性SVM分类原理(求解损失) 三、重要参数 1. kernel(核函数) 2 .C(硬间隔与软间隔) 四、sklearn中的支持向量机(自查&#…...

Elastic Observability 8.15:AI 助手、OTel 和日志质量增强功能
作者:来自 Elastic Alex Fedotyev, Tom Grabowski, Vinay Chandrasekhar, Miguel Luna Elastic Observability 8.15 宣布了几个关键功能: 新的和增强的原生 OpenTelemetry 功能: OpenTelemetry Collector 的 Elastic 分发:此版本…...

Unity3D ECS架构的优缺点详解
前言 Unity3D作为一款强大的游戏开发引擎,近年来在性能优化和架构设计上不断进化,其中ECS(Entity-Component-System)架构的引入是其重要的里程碑之一。ECS架构通过重新定义游戏对象的组织和处理方式,为开发者带来了诸…...

理解Go语言中多种并发模式
Go 的同步原语使实现高效的并发程序成为可能,并且选择合适的同步原语和并发模式可以更加容易地实现并发的可能,减少错误的发生。这里谈论的并发模式是只在 Go 语言中常见的并发的“套路” ,一种可解决某一类通用场景和问题的惯用方法。 1. 并发模式概述 我们先来回顾下同步…...

C++ primer plus 第17 章 输入、输出和文件:文件输入和输出03:文件模式:二进制文件
系列文章目录 17.4.5 文件模式 程序清单17.18 append.cpp 程序清单17.19 binary.cpp 文章目录 系列文章目录17.4.5 文件模式程序清单17.18 append.cpp程序清单17.19 binary.cpp17.4.5 文件模式1.追加文件来看一个在文件尾追加数据的程序。程序清单17.18 append.cpp2.二进制文…...

网络安全之sql靶场(11-23)
sql靶场(11-23) 目录 第十一关(post注入) 第十二关 第十三关 第十四关 第十五关 第十六关 第十七关 第十八关 第十九关 第二十关 第二十一关 第二十二关 第二十三关 第十一关(post注入) 查看…...

WordPress网站被入侵,劫持收录事件分析
7.15,网站被入侵,但是直到7月17日,我才发现被入侵。 16日,17日正常更新文章,17日查询网站收录数据时,在站长资源平台【流量与关键词】查询上,我发现了比较奇怪的关键词。 乱码关键词排名 起初…...