ARM底层汇编基础指令

news2024/11/29 5:51:25

汇编语言的组成

  • 伪操作
    • 不参与程序执行,但是用于告诉编译器程序怎么编译
    • .text .global .end .if .else .endif .data
  • 汇编指令
    • 编译器将一条汇编指令编译成一条机器码,在内存里一条指令占4字节内存,一条指令可以实现一个特定的功能
  • 伪指令
    • 不是指令,看起来像是一条指令,可以实现和指令类似的功能。一条伪指令实际上可能是由多条指令共同实现
  • 注释
    • 单行注释:@
    • 多行注释:/* */
  • 条件编译
.if 0
@text
.else
@text
.endif

汇编指令的介绍

  • 基本数据操作指令
    • 数据搬移指令:=
    • 数据位移指令:<< >>
    • 数据算数运算指令:+ - * /
    • 位运算指令:$ |~ ^
    • 数据比较指令:
  • 跳转指令
  • 内存读写指令
  • 状态寄存器读写指令
  • 软中断指令

汇编指令的基本语法格式

基本格式: <opcode>{cond}{s} Rd,Rn,#oprand2
解释:
    opcode:指令码
    cond:条件码
        指令不加条件码,指令默认无条件执行
        指令加条件码,指令有条件执行
    s:状态位
        指令不加s,指令执行的结果不会影响CPSR寄存器
        指令加s,指令执行的结果会影响CPSR寄存器
    Rd:目标寄存器
    Rn:第一操作寄存器
    #oprand2:第二操作数
        1)立即数
        2)有效数:将一个数取反之后,变成立即数
        3)寄存器
        4)经过移位的寄存器
 
注意事项:
1)汇编指令中不区分大小写
2)汇编指令不需要以;号结尾
3)<opcode>{cond}{s}:需要连在一起写
4)Rd,Rn,#oprand2:需要用逗号分隔开
5) <opcode>{cond}{s}和Rd,Rn,#oprand2需要用空格分隔开

数据搬移指令

  • 指令码:mov mvn
  • 格式:<opcode>{cond}{s} Rd,#oprand2
@代码1:
    mov r0,#0xf @ r0 = 0xf
	mov r1,#0xff
	@ mov r2,#0xfff @ error
	@ mov r3,#0xffff @ error
	@ mov r4,#0xfffff @ error
	mov r5,#0xffffff
	mov r6,#0xfffffff
	mov r7,#0xffffffff
 /*------------------ ------------------ ---------------*/
@ 代码2:
 	mvn r5,#0xff  @ 0xff按位取反之后,赋值给r5
	mov r0,#0xff000000 @ 0xff 8
	mov r1,#0x1f800000 @ 0x7e  10
	mov r2,#0x00ffffff   @ ~r2 = 0xff000000
	mov r3,#0x0fffffff   @ ~r3 = 0xf0000000
	mov r4,#0xffffffff   @ ~r4 = 0x00000000

立即数判断

在这里插入图片描述

  • 立即数就是队#号后面的这个数有要求
  • 首先要从你判断的这个数中间找到0~0xff之间的数(需要将要判断的这个数所有的1包含)
  • 将找到的这个0~0xff之间的数,循环右移偶数位(低位移出,补到高位)
  • 如果能够得到你要判断的那个数,说明你这个数是一个立即数

示例代码

要判断的数:0xf
           0000 0000 0000 0000 0000 0000 0000 1111
找到0~0xff: 0xf
           0000 0000 0000 0000 0000 0000 0000 1111
循环右移位数:0
是否为立即数:是
 
要判断的数:0xff
           0000 0000 0000 0000 0000 0000 1111 1111
找到0~0xff: 
           0xff
循环右移位数:
            0
是否为立即数:是
 
要判断的数:0xfff
           0000 0000 0000 0000 0000 1111 1111 1111 
找到0~0xff: 
           不能
循环右移位数:
是否为立即数:不是
 
要判断的数:0xf000000f
           1111 0000 0000 0000 0000 0000 0000 1111
找到0~0xff: 
           0xff
           0000 0000 0000 0000 0000 0000 1111 1111
循环右移位数:4
是否为立即数:是
 
要判断的数:0xff000000
           1111 1111 0000 0000 0000 0000 0000 0000
找到0~0xff: 
           0xff
           0000 0000 0000 0000 0000 0000 1111 1111         
循环右移位数:8
是否为立即数:是
 
要判断的数:0x1fe00000
           0001 1111 1110  0000 0000 0000 0000 0000
找到0~0xff: 
           0xff
           0000 0000 0000 0000 0000 0000 1111 1111            
循环右移位数:11
是否为立即数:不是
 
要判断的数:0x1f800000
           0001 1111 1000  0000 0000 0000 0000 0000
找到0~0xff: 
           0x7e
           0000 0000 0000 0000 0000 0000 0111 1110
循环右移位数:10
是否为立即数:是

伪指令(将非立即数保存至寄存器中)

伪指令:
    LDR 目标寄存器,=数值
    将指定的数据放在目标寄存器中
    
ex:LDR r1,=0X12345678

移位操作指令

  • 格式:<opcode>{cond}{s} Rd,Rn,#oprand2
  • 指令码
    • lsl:逻辑左移 高位移出,低位补0
    • lsr:逻辑右移 低位移出,高位补0
    • asr:算数右移 有符号数右移,低位移出,高位补符号位
    • ror:循环右移 低位移出,补到高位

示例

	mov r0,#0xff
	@1.将0xff逻辑右移4位,并存入r1寄存器中
	lsr r1,r0,#0x4  @ r1 = r0 >> 4 =  0xf
	@ 0000 0000 0000 0000 0000 0000 1111 1111
	@ 0000 0000 0000 0000 0000 0000 0000 1111
	
	@2.将r1逻辑左移4位,并存入r2寄存器中
	lsl r2,r1,#0x4  @ r2 = r1 << 4 = 0xf0
	@ 0000 0000 0000 0000 0000 0000 0000 1111
	@ 0000 0000 0000 0000 0000 0000 1111 0000
	
	ldr r3,=0x800000f0
	@将r3寄存器中的值,算数右移4位,并存入r4寄存器中
	asr r4,r3,#0x4  @ r4 = 0xf800000f
	@ 1000 0000 0000 0000 0000 0000 1111 0000
	@ 1111 1000 0000 0000 0000 0000 0000 1111
	@将r4寄存器中的值,循环右移4位,并存入r5寄存器中
	ror r5,r4,#0x4  @ r5 = 0xff800000
	@ 1111 1000 0000 0000 0000 0000 0000 1111
	@ 1111 1111 1000 0000 0000 0000 0000 0000

位运算指令

  • 格式:<opcode>{cond}{s} Rd,Rn,#oprand2
  • 口诀:看到清零用& 看到置1用|
and:按位与(&)------>与0清0,与1不变
orr:按位或(|) ------>或0不变,或1置1
eor:按位异或(^) ------>异或0不变,异或1取反
bic:按位清除  ------> 哪一位写1,对应的位进行清0

示例

ldr r0,=0x12345678	
  	@ 1> 将R0寄存器中的第[4]位清0,保持其他位不变
		bic r1,r0,#(0x1 << 4)
		and r1,r0,#(~(0x1 << 4))
	@ 2> 将R0寄存器中的第[7]位置1,保持其他位不变
		orr r2,r0,#(0x1 << 7)
	@ 3> 将R0寄存器中的第[31:28]位清0,保持其他位不变
		bic r0,#(0xf << 28)
		and r0,#(~(0xf << 28))
	@ 4> 将R0寄存器中的第[7:4]位置1,保持其他位不变
		orr r0,#(0xf << 4)
	@ 5> 将R0寄存器中的第[15:11]位修改为10101,保持其他位不变
		@ 先置1,在清0
		orr r0,#(0x1f << 11)
		and r0,#(~(0x1 << 12))
		and r0,#(~(0x1 << 14))
		@ 先清0,在置1 ----->重点掌握
		and r0,r0,#(~(0x1f << 11))

		orr r0,r0,#(0x15 << 11)

算数运算指令

指令码:add adc sub sbc mul
基本格式: <opcode>{cond}{s} Rd,Rn,#oprand2
add: 普通加法指令
adc:带进位加法指令
sub:普通减法指令
sbc:带借位减法指令
mul:乘法指令  格式:<opcode>{cond}{s} Rd,Rn   

示例

1.ADD:加法
  ex1:  mov r1,#1
	  mov r2,#2
	 add r3,r1,r2@r3=r1+r2
  ex:
      mov r1,#0XFFFFFFFE
	mov r2,#2
	addS r3,r1,r2@r3=r1+r2  @运算的结果影响到条件位
2.SUB
        mov r1,#0XFFFFFFFE
	mov r2,#2
	sub r3,r1,r2@r3=r1-r2
 ex2:
         mov r1,#0XFFFFFFFE
	mov r2,#2
	subs r3,r2,r1@r3=r2-r1 
3.ADC
mov r1,#0XFFFFFFFE
mov r2,#2
	ADDS r3,r2,r1 @r3=r1+r2 
	ADC R4,R2,#3  @R4=R2+3+cpsr(C位)  6 
 
4.sbc:减法运算考虑条件位
mov r1,#0XFFFFFFFE
	mov r2,#2
	  SUBS r3,r2,r1 @r3=R2-R1    4
	sbC R4,R1,#3  @R4=R1-3-CPSR(C位取反)

64位数据进行算术运算

原则:
一个 64位数保存在两个寄存器
高32位运算,低32位运算
     mov r1,#0XFFFFFFFE  @保存第一个数据的低32位
	mov r2,#2@保存第一个数据的高32位
	mov r3,#3 @保存第二个数据的低32位
	mov r4,#4 @保存第2数据的高32位
	@低32位运算要求影响条件位
	ADDS R5,R1,R3@R5保存运算后结果的低32位
	ADC R6,R2,R4@R6寄存器保存运算结果的高32位,需要考虑条件位

比较指令

指令码:cmp
基本格式: <opcode>{cond} Rn,#oprand2
1)比较指令没有目标寄存器
2)比较指令本质做减法运算
3)比较指令的执行结果会影响CPSR寄存器的NZCV位,不需要加s
4)比较指令需要和条件码搭配使用
5)前面所有学习的指令都属于无条件指令,比较指令属于有条件执行
	/*
		比较两个数大小
		第一个数比第二个数大:第一个数减第二个数
		第一个数比第二个数小:第二个数减第一个数
	*/
	mov r0,#0x3
	mov r1,#0x4
	cmp r0,r1
	subhi r0,r0,r1  @ r0 = r0 - r1
	subcc r1,r1,r0  @ r1 = r1 - r0

在这里插入图片描述

跳转指令

指令码:b 
格式:b {cond} 标签
b指令码:有去无回,不会保存函数的返回地址到LR寄存器中
    -------------------
    b loop
    ------------------- 
    loop:
         -------------------
/****************************************************/
指令码: bl
格式:bl{cond} 标签
bl指令码:有去有回,会保存函数的返回地址到LR寄存器中
    -------------------
    bl loop
    -------------------  ----->会保存函数的返回地址到LR寄存器中
    loop:
         -------------------

示例

mov r0,#0x1
	mov r1,#0x2
	bl add_func  @ 跳转到add_func标签下第一条指令执行
	mov r3,#0x3
	b stop
	
add_func:
	add r0,r0,r1
	mov pc,lr @手动恢复现场 pc = lr

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三翼鸟三周年:三次升级,全面引领

被誉为“竞争战略之父”的迈克尔波特&#xff0c;曾提出过“差异化竞争”的理念。 简单说&#xff0c;企业在“差异化竞争”中要做到三大法则&#xff1a; 人无我有、人有我优、人有我新。 在许多优秀企业的身上&#xff0c;都能看到差异化的影子&#xff0c;比如华为、海尔…

基于Java的校园书法绘画比赛评分系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言管理员功能评委功能参赛者功能具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新…

EasyExcel 优雅实现 Excel 导入导出

一、简介 EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下&#xff0c;快速完成Excel的读、写等功能。 二、特点 快速 快速的读取excel中的数据。 简洁 映射excel和实体类&#xff0c;让代码变…

26967-2011 一般用喷油单螺杆空气压缩机

声明 本文是学习GB-T 26967-2011 一般用喷油单螺杆空气压缩机. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了一般用喷油单螺杆空气压缩机(以下简称"单螺杆空压机")的术语和定义、型号、基本 参数、要求、试验方法、…

Matlab坐标轴标签中文设置宋体

对y坐标输出中文宋体 新罗马字符 x[1,2,3,4,5,6,7]; plot(x) ylabel(\fontname{宋体}\fontsize{20}长度\fontname{Times New Roman}\fontsize{10} (μm))可以灵活设置字体和大小,其图片如下图所示 也可以对全图的文字设置同一个字体 set(gca,FontSize,9,Fontname, Times New…

[vue-admin-template实战笔记]

1.克隆项目 git clone gitgitee.com:panjiachen/vue-admin-template.git 2.安装依赖 npm install 3.运行项目就会自动打开网页&#xff0c;并且热部署插件 npm run dev 4.查看代码 //将vue-admin-template拖入到idea中即可查看代码 1)并且发现&#xff0c;常用的东西已经集…

c# 委托 事件 lambda表达式

委托 C/C中的函数指针实例&#xff1a; typedef int (*Calc)(int a, int b); //这里必须加括号 int Add(int a, int b) {return a b; } int Sub(int a, int b) {return a - b; } int main() {int x 100;int y 200;int z 0;Calc funcPoint1 &Add;Calc funcPoint2 &am…

【实践成果】Splunk 9.0 Configuration Change Tracking

Splunk 9.0 引入了新的功能&#xff0c;一个很重要的一个&#xff0c;就是跟踪conguration 文件的变化&#xff1a; 这个很重要的特性&#xff0c;在splunk 9.0 以后才引入&#xff0c;就看server.conf 配置中&#xff0c;9.0 以后的版本才有&#xff1a; server.conf - Splu…

【STL巨头】set、map、multiset、multimap的介绍及使用

set、map、multiset、multimap的介绍及使用 一、关联式容器二、键值对键值对概念定义 三、setset的介绍set的使用set的模板参数列表set的构造set的迭代器set的容量emptysize set的修改操作insertfind && erasecountlower_bound 和 upper_bound Multiset的用法 四、mapm…

WebGL笔记:绘制矩形面的几种方式以及封装封装多边形对象来绘制不同图形

绘制矩形面 可以绘制的面只有三角面&#xff0c;要绘制矩形面的话&#xff0c;只能用两个三角形去拼 1 &#xff09; 使用 三角带 TRIANGLE_STRIP 绘制矩形 回顾一下之前的规律&#xff1a; 第一个三角形&#xff1a;v0>v1>v2第偶数个三角形&#xff1a;以上一个三角形…

预编译(2)

#和## #运算符&#xff1a; #运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带参数的宏的替换列表中。 #运算符所执⾏的操作可以理解为“字符串化”。 举例&#xff1a; 当我们有⼀个变量 int a 10; 的时候&#xff0c;我们想打印出&#xff1a; the value of …

volatile修饰数组

结论&#xff1a;volatile修饰对象或数组时&#xff0c;只能保证他们的引用地址的可见性。 非volatile数组的可见性问题 public class Test {static int[] a new int[]{1};public static void main(String[] args) {new Thread(() -> { //线程Atry {Thread.sleep(1000);}…

ElasticSearch一对多关系方案

一、前言 使用MySQL做为存储&#xff0c;表与表之间有很多是一对多关系&#xff0c;比如订单和订单商品明细&#xff0c;客户和客户地址等等&#xff0c;但是因为ES本身是扁平化文档结构&#xff0c;一般不同索引之间是没有关系的&#xff0c;ES在处理这种关系时相比MySQL并不…

Python计算巴氏距离

Python计算巴氏距离 巴氏距离简介 在统计中&#xff0c;巴氏距离&#xff08;Bhattacharyya Distance&#xff09;测量两个离散或连续概率分布的相似性。它与衡量两个统计样品或种群之间的重叠量的巴氏系数密切相关。巴氏距离和巴氏系数以20世纪30年代曾在印度统计研究所工作…

分布式事务-TCC异常-幂等性

1、幂等性问题&#xff1a; 二阶段提交时&#xff0c;如果二阶段执行成功通知TC时出现网路或其他问题中断&#xff0c;那么TC没有收到执行成功的通知&#xff0c;TC内部有定时器不断的重试二阶段方法&#xff0c;导致接口出现幂等性问题。 2、解决方法 和空回滚问题一样也是…

Elastic SQL 输入:数据库指标可观测性的通用解决方案

作者&#xff1a;Lalit Satapathy, Ishleen Kaur, Muthukumar Paramasivam Elastic SQL 输入&#xff08;metricbeat 模块和输入包&#xff09;允许用户以灵活的方式对许多支持的数据库执行 SQL 查询&#xff0c;并将结果指标提取到 Elasticsearch。 本博客深入探讨了通用 SQL …

基于SpringBoot的课程答疑系统

目录 前言 一、技术栈 二、系统功能介绍 学生信息管理 科目类型管理 老师回答管理 我的收藏管理 学生问题 留言反馈 交流区 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#x…

SPSS探索性分析

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件可在个人主页—…

求解平面上物体的有向3d包围盒

算法流程&#xff1a; &#xff08;1&#xff09;点云下采样&#xff08;体素滤波&#xff09;&#xff1b; &#xff08;2&#xff09;ransac算法分割拟合地面平面&#xff1b; &#xff08;3&#xff09;裁剪工作区域&#xff08;指定空间中四个点&#xff0c;裁剪点云只保留…

C++_基础语法

一、关键字 常用语法 #include<iostream>using namespace std;// 全局常量 #define DAY 30void main() {/** 变量与输出*/// 局部常量const int year 2023;// 控制台输出cout << "hello world" << endl;cout << "天&#xff1a;"…