汇编指令命令

ARM汇编指令学习

  • 工程搭建

汇编编程环境搭建

HN0AE-522LW-NNRAF-63PUS-7IGFH-YF58D

配置编译工具链

为工程配置链接脚本(map.lds)

将map.lds 复制到工程文件夹(在桌面创建的ARM-ASM文件)

创建汇编文件

接下来我们需要建立一个start.s汇编文件添加到我们的工程中去

  • 汇编指令学习

c语言中哪些代码可以生成汇编指令?

1》带#号预处理,辅助编译器怎么编译,编译什么内容

预处理器是C语言编译器的一个组成部分,它在编译代码之前对代码进行处理。预处理器指令以#号开头,告诉编译器在编译代码之前执行一些操作。其中,#include指令用于将头文件包含到源代码中,#define指令用于定义宏。预处理器的主要作用是辅助编译器编译代码。 例如在编译时将头文件中的函数声明插入到源代码中,或者将宏替换为实际的值。预处理器处理完代码后,编译器将生成目标代码,最终生成可执行文件。

2》带;号的语句,可以编译生成指令

在编译器中,分号是语句结束的标志,编译器会将分号之前的语句编译成指令并添加到指令序列中。

汇编整体分类

1》指令:编译完生成一条机器码存储在内存单元当中,CPU执行时能完成对应的操作(类似于C中的语句)

2》伪操作(相当于c中的#的内容,告诉编译器怎么编译):不会生成机器码也不会占用内存,其作用是告诉编译器怎样编译(类似于C中的预处理指令)

3》伪指令:不是指令,编译器在编译时将其替换成等效的指令 

 (如:cpu中没有乘法器,对应没有乘法指令,3*3 ---》用加法器实现3+3+3,替换实现)

 汇编中注释代码用@或;注释一行 ,/* */注释一段代码 

指令分类

1.数据处理指令: 对数据进行逻辑、算术运算

2.跳转指令: 实现程序的跳转,本质是修改PC

3.Load/Store指令: 对内存的读写操作

4.状态寄存器传送指令: 对CPSR进行读写操作

5.异常中断产生指令: 触发软中断,常用于内核的系统调用  //SWI:软中断

6.协处理器指令: 操作协处理器的指令

//如3*3 ---》用加法器实现3+3+3,比较慢。我们可以外接一个协处理器(乘法器)(每个协处理器的功能比较单一),协处理器指令就是操作这个协处理器的,用的比较多的cp15协处理器。

汇编指令代码框架

.text            @声明一段代码
.global _start    @将_start 声明为一个全局的符号,其他.s文件也可以引用
                    @如调用函数  func  :  .global func
_start:            @汇编的入口
                    @汇编代码段
     
.end                @汇编的结束
(最后空一行,否则有警告)

指令的语法格式(不用记)

<opcode{<cond>}{S}> <Rd>, <Rn>, <Operand2>
<操作码> <目标寄存器Rd> <第一操作寄存器Rn> <第二操作数Operand2>
;第一个位置必须是寄存器,第二操作数可以是寄存器,也可以是立即数

<opcode{<cond>}{S}> <Rd>, <Rn><Operand2>

opcode:指令的名字

cond:条件码(if else),可以省略不写,默认指令是无条件执行

S:状态标志

加s,指令的执行结果影响CPSR的NZCV位,

不加s,无影响

Rd:目标寄存器

Rn:第一个操作寄存器

oprand2:第二个操作数,可以是普通寄存器,可以是立即数

注:指令的名字,条件码,s连到一起写,指令名和目标寄存器之间使用空格,寄存器和数据之间使用逗号隔开,指令中的字符不区分大小写

  1. 数据处理指令

数据搬移指令  mov

如果是立即数,前面必须加#号

什么是立即数?

立即数

立即数通常是指在立即寻址方式指令中给出的数。可以是8位、16位或32位,该数值紧跟在操作码之后。

寻址方式:

寻址方式_百度百科

立即数是保存在指令中的数,取指令的同时将值取过去,和普通变量的区别是,变量保存在内存中的数据,需要单独取值运算。

立即数的本质:立即数是包含在指令当中的数据(即属于指令的一部分)

立即数的优点:读取指令的同时也将立即数读取到了内存中,速度快

立即数的缺点:数量有限

怎么判断一个数是否立即数?

给定一个数,将这个数中的所有的1,可以组合成一个0-255之间的数,将0-255之间的这个数,循环右移偶数个位数,如果可以得到给定的这个数,说明是立即数。

问:只要挨着的就是立即数?对吗?(对)

注:使用mov 给寄存器里面存放值的时候,#号后面需是有效数(1:立即数,2:取反之后是立即数),如果不是立即数需要用ldr指令进行存放。

如果不是立即数,用伪指令ldr  赋值

PC寄存器讲解

指令的执行三步:取址,译码,执行(PC永远指向当前正在取指指令的地址)

算术运算指令

数据运算指令格式

<操作码><目标寄存器><第一操作寄存器><第二操作数>

ADD R3,R1,R2;

操作码 指定当前指令是哪种运算

目标寄存器 存放运算结果

第一操作寄存器 存放参与运算的一个数据(只能是寄存器)

第二操作数 存放参与运算的另一个数据(可以是寄存器/立即数)

算术运算指令

add加法 adc 带进位的加法

sub 减法 sbc 带借位的减法

mul乘法 (乘法运算的R2(第二操作数)不能为立即数) 

add 普通加法

adc 带进位加法

假设有两个64位的数相加

第一个64位数,R0放低32位数,R1放高32位数;

第一个64位数,R2放低32位数,R3放高32位数;

结果放在R4放低32位数,R5放高32位数;

减法运算,产生借位时c=1,否则 c=0;

sub 普通减法

subs 减法(刷新CPSR)

减法指令执行时,有借位时 CPSR 'C' 位置 1

mul 乘法

注意:mul r4, r3, #0x4  @ 错误------>乘法指令的第二个操作数只能是一个寄存器

与 and 、或orr、 异或eor、 左移lsl、 右移lsr

	mov r0,#1
	mov r1,#2
	mul r2,r1,r0
	and r3,r1,#1	@与 R3 = R1&1 -->0
	orr r4,r2,r1	@或 R4 = R2|R1-->2
	eor r5,r2,r1	@异或 R5 = R2^R1-->0
	lsl r6,r2,r1	@左移 R6 = R2<<R1-->8
	lsr r7,r2,r1	@右移 R7 = R2>>R1-->0

  1.  跳转指令

实现程序的跳转,本质是更改PC

修改PC

不建议使用,因为需要查询地址

b   bl :指令跳转

格式:b/bl Label 

Label: 指令

相当C语言的函数调用

b指令(不带返回的跳转)       

      不保存返回地址的跳转(返回地址不保存到lr中)

一路向前,不返回

bl指令(带返回的跳转指令)

将LR的值修改成跳转指令下一条指令的地址

再将PC的值修改成跳转标识符下指令的地址

补充了解:

指令条件码表:可跟的判断条件成立跳转(NZCV在用于判断两者之间关系使用比较多)

练习

实现以下逻辑
unsigned int r1 = 9;
unsigned int r2 = 15;
while(1)
{
    if(r1 == r2)   //cmp
    goto stop;
    if(r1 > r2)
    r1 = r1 - r2;
    if(r1 < r2)
    r2 = r2 - r1;    //subcc r2,r2,r1
}
stop:
    while(1);

  1. load/store指令(批量操作)

对内存的读写操作,将运算结果从cpu写到内存

可用地址查找:(我们不用查找,脚本文件中配置了内存空间的分配) 

单寄存器操作指令 ldr / str

  1. 格式:ldr/str  Rm, [Rn]

ldr:

str:写

Rm: 存储是数据

Rn:存储的数据,地址

1>前索引

	mov r1,#0xffffffff
	mov r2,#0x40000000
	str r1,[r2,#8]		@基址加变址寻址把R1存在0x40000000+8的内存里

2>后索引

mov r1,#0xffffffff
mov r2,#0x40000000
str r1,[r2],#4		@将R1寄存器的内容存到[R2]地址,然后R2=R2+4

目的:可以做连续存储,压栈时用的比较多  存完一个数,他就把地址自动指向下一个了

3>自动索引(前后索引)

	mov r1,#0xffffffff
	mov r2,#0x40000000
	str r1,[r2,#4]!    @将R1寄存器的内容存到[R2+4]地址,然后R2=R2+4

批量寄存器操作指令ldm/stm 

1、将r1到r4中的值存储到r0指向地址空间中,连续16个字节的地址空间

stm r0, {r1-r4}

2、将r0指向的地址空间中,连续的16个字节的数据,读到r5-r8寄存器中

ldm r0, {r5-r8}

3、如果寄存器列表中的寄存器编号既有连续又有不连续,连续的使用 - 隔开 不连续的使用 ,

stm r0, {r1-r3,r5}

4、不管寄存器列表中的寄存器编号顺序如何变化,都是小地址对应小编号的寄存器高地址对应大编号的寄存器

stm r0,{r4,r2,r1,r3}

ldm r0,{r8,r6,r5,r7}

4、栈的操作指令 stmfd / ldmfd

栈的种类

空栈(Empty)

栈指针指向的地址是空的,在栈中存储数据时,可以直接存储,存储完成之后需要将栈指针再次指向空的位置。

满栈(Full)

栈指针指向的地址有数据,在栈中存储数据时,需要先将栈指针,指向一个空的位置,然后在存储数据。

增栈(Ascending)

栈指针向高地址方向移动

减栈(Descending)

栈指针向低地址方向移动

操作栈的方式

满增栈,满减栈,空增栈,空减栈

FA:Full Ascending 满增

FD:Full Descending 满减

EA:Empty Ascending 空增

ED:Empty Descending 空减

ARM默认采用的是满减栈

stmfd/ldmfd<code> sp!, {寄存器列表}

stmfd sp!, {r1-r5}(写) (压栈)

更新栈指针指向的地址空间

ldmfd sp!, {r6-r10}(读) (出栈)

特殊:(CPU寄存器不连续)

stmfd sp!, {r1-r5,lr}(写) (压栈

ldmfd sp!, {r6-r10,pc}(读) (出栈)    //r1-r5出栈给r6-r10, 将lr的值出栈给pc

程序中运用

ldr r1,=0x11111111
	ldr r2,=0x22222222
	ldr r3,=0x33333333
	ldr r4,=0x44444444
	ldr r5,=0x55555555
	ldr sp,=0x40001020
	
	stmfd sp!,{r1-r5}
	bl func
	ldmfd sp!,{r1-r5}
	ldr r6,=0x66666666
	
	loop:
loop
	func:
	ldr r1,=0x1
	ldr r2,=0x2
	ldr r3,=0x3
	ldr r4,=0x4
	mov pc,lr

栈的应用-》叶子函数的调用过程

叶子函数是指一个函数内部没有调用其他函数的函数,也就是说,它是程序调用树的末端节点,不依赖于其他函数。

	MOV SP,#0X40000020
MAIN:
	MOV R1,#3
	MOV R2,#2
	BL F
	ADD R3,R1,R2
T:
	B T
F:
	STMFD SP!,{R1,R2}
	MOV R1,#5
	MOV R2,#4
	ADD R3,R1,R2
	LDMFD SP!,{R1,R2}
	MOV PC,LR

栈的应用-》非叶子函数的调用过程

非叶子函数是指一个函数内部调用了其他函数的函数,也就是说,它不是程序调用树的末端节点,可以被其他函数调用。

	MOV SP,#0X40000020
MAIN:
	MOV R1,#3
	MOV R2,#2
	BL F
	ADD R3,R1,R2
T:
	B T
F:
	STMFD SP!,{R1,R2,LR}
	MOV R1,#5
	MOV R2,#4
	BL D
	ADD R3,R1,R2
	LDMFD SP!,{R1,R2,LR}
	MOV PC,LR
D:
    STMFD SP!,{R1,R2,LR}
	MOV R1,#6
	MOV R2,#7
	ADD R3,R1,R2
	LDMFD SP!,{R1,R2,LR}
	MOV PC,LR

5、状态寄存器操作指令

注:刚上电是在SVC模式下

对CPSR进行读写操作

//其他都不能动CPSR   (SWI 指令是linux内核有,所以arm为了匹配才有的指令)

(CPSR保存cpu的状态、模式、中断中断开关、运算状态,非常重要,不能任意更改,只有一类指令能操作这个寄存器)

读cpsr指令 mrs 

写cpsr指令 msr  

	@状态寄存器操作指令		mrs / msr
	ldr r1,=0x12345678
	mrs r0,cpsr			@读cpsr的值到r0
	msr cpsr_c,#0x1f	@修改cpsr的值,cpsr_c 指的是后八位控制位
	msr cpsr_c,#0x13	@切换到svc
	msr cpsr_c,#0x10	@切换到user,非特权模式
	ldr r2,=0x87654321
	msr cpsr_c,#0x13	@切换到svc

注:修改CPSR的控制域(bit[7:0]),修改CPSR时必须指定修改哪个区域;USER模式下不能修改CPSR的值,防止应用程序修改CPU状态,保护操作系统;CPSR_C修改的是CPSR的低八位ctrl(控制)域,一般都只修改C域

6、异常中断指令

触发软中断,常用于内核的系统调用   //SWI:软中断

@异常中断指令		软中断指令swi
	ldr r1,=0x12345678
	ldr r2,=0x22345678
	ldr r4,=0x42345678
	msr cpsr_c,#0x10	@切换到user模式
	ldr r3,=0x32345678
	swi #1		@软中断
	@执行软中断指令:spsr、lr、cpsr、pc 均发生了改变
	
	ldr r6,=0x52345678

为什么会出现以上情况?做完的请先自行阅读下方文档

异常源及处理过程

7、协处理器指令

操作协处理器的指令(一般用不到-----协助cpu处理数据)

1.数据运算
2.内存访问
3.与主处理器通信
MRC 将协处理器中寄存器的内容读取到ARM处理器的寄存器中
MCR 将ARM理器中寄存器的内容读取到协处理器的寄存器中

协处理器指令

  1. 协处理器数据运算指令

CDP

  1. 协处理器储存器访问指令

STC 将协处理器中的数据储存到存储器

LDC 将存储器中的数据读取到协处理器中

  1. 协处理器寄存器传送指令

MRC 将协处理器中寄存器的数据传送到ARM处理器中的寄存器

MCR 将ARM处理器寄存器中的数据读取到协处理器寄存器中

伪指令

本质:本身不是指令,但是cpu替换成等效的操作。

举例1
延时一个指令周期(耗时一条指令的时间)  (cpu没有这个指令)
	NOP    ;执行NOP和MOV R0,R0一个效果,执行NOP,cpu替换成MOV R0,R0
	MOV R0,R0  
LDR的两种形式
;->指令
        LDR R1,[R2]     
;->伪指令
	    LDR R1,=0x12345678     ;R1 = 0x12345678
;可以将任何一个32bit的数据放入寄存器

伪操作

指令是arm公司规定的,而伪操作是编译器规定的,不同的编译器伪操作指令不同。

(我们学的linux,用linux的编译器)

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

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

相关文章

基于Microchip 光伏逆变器方案

小编杂谈新能源已经完成了至少5期的博文了&#xff0c;Boss告诉小编&#xff0c;如果还不介绍我们的产品和方案&#xff0c;黄花菜都凉了&#xff0c;所以小编这期博文就重点介绍一下Microchip在储能上的产品介绍&#xff0c;重点聊聊Microchip储能中使用的光伏逆变器的解决方案…

沉浸文旅体验!实时云渲染助力2023广东旅博会智慧文旅元宇宙体验馆上线

2023广东国际旅游产业博览会&#xff08;以下简称旅博会&#xff09;于9月15-17日在广州中国进出口商品交易会展馆A区举办&#xff0c;共设有国际展区、国内展区、智慧文旅展区、文化创意展区、旅游商品展区等五大展区&#xff0c;汇聚了来自全球近40个国家和地区的近千家参展商…

综述 2022-Genome Biology:“AI+癌症multi-omics”融合方法benchmark

Leng, Dongjin, et al. "A benchmark study of deep learning-based multi-omics data fusion methods for cancer." Genome biology 23.1 (2022): 1-32. 被引次数&#xff1a;34作者单位 红色高亮表示写论文中可以借鉴的地方 一、方法和数据集 1. 3个数据集&…

【✅如何针对大Excel做文件读取?】

✅如何针对大Excel做文件读取&#xff1f; &#x1f7e9;如何针对大Excel做文件读取&#x1f7e9;XSSFWorkbook文件读取&#x1f7e9;EasyExcel文件读取 ✅扩展知识&#x1f7e9; EasyExcel简介&#x1f7e9;EasyExcel 为什么内存占用小&#xff1f; &#x1f7e9;如何针对大Ex…

MySQL使用Not in查询效率慢的优化

引言 问题复盘&#xff0c;在查询某个数据不在另一个表中&#xff0c;查询时间非常慢&#xff0c;10几秒。究其原因not in不走索引。那么怎么解决优化呢&#xff0c;下面是简单记录。 原SQL select * from test where a not in ( select a from test2 where status in (1, 2…

由@EnableWebMvc注解引发的Jackson解析异常

同事合了代码到开发分支&#xff0c;并没有涉及到改动的类却报错。错误信息如下&#xff1a; Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.conv…

重新认识Word——给图、表、公式等自动编号

重新认识Word——给图、表、公式等自动编号 给图增加题注题注失败的情况给图添加“如图xx-xx所示” 给公式插入题注第一步——先加题注第二步——设置两个制表符 解决题注“图一-1”的问题 前面我们已经学习了如何引用多级列表自动编号了&#xff0c;现在我们有第二个问题&…

数字病理图像分析的开源软件qupath学习 ①

介绍&#xff1a;QuPath是一种新的生物图像分析软件&#xff0c;旨在满足对用户友好、可扩展、开源解决方案日益增长的需求&#xff0c;用于数字病理学和全玻片图像分析。除了提供全面的肿瘤识别和高通量生物标志物评估工具外&#xff0c;QuPath 还为研究人员提供了强大的批处理…

怎么抠图换背景?这三个方法让你轻松抠图

怎么抠图换背景&#xff1f;抠图是每个独立站商家每天必不可少的工作&#xff0c;简单一张图用PS进行抠图还好&#xff0c;但如何多张图&#xff0c;用PS就效率非常低&#xff0c;且需要专业的PS技能才能上手实现精准抠图的目的&#xff0c;那么怎么快速抠图换背景呢&#xff0…

【MySQL学习】概述

文章目录 1. mysql的启动和停止命令2. 客户端连接3. 数据模型 1. mysql的启动和停止命令 通过指令启动或停止&#xff0c;以管理员身份运行cmd&#xff0c;进入命令行执行如下指令&#xff1a; &#xff08;1&#xff09;启动myaql net start mysql&#xff08;2&#xff09;…

TikTok科技趋势:平台如何引领数字社交革命?

TikTok作为一款颠覆性的短视频应用&#xff0c;不仅改变了用户的娱乐方式&#xff0c;更在数字社交领域引领了一场革命。本文将深入探讨TikTok在科技趋势方面的引领作用&#xff0c;分析其在数字社交革命中的关键角色&#xff0c;以及通过技术创新如何不断满足用户需求&#xf…

虚拟化嵌套

在理论上,可以在虚拟机(VM)内运行一个hypervisor,这个概念被称为嵌套虚拟化: 我们将第一个hypervisor称为Host Hypervisor,将VM内的hypervisor称为Guest Hypervisor。 在Armv8.3-A发布之前,可以通过在EL0中运行Guest Hypervisor来在VM中运行Guest Hypervisor。然而,这…

智能冶钢厂环境监控与设备控制系统(边缘物联网网关)

目录 1、项目背景 2、项目功能介绍 3、模块框架 3.1 架构框图 3.2 架构介绍 4、系统组成与工作原理 4.1 数据采集 4.2 指令控制 4.3 其他模块 4.3.1 网页、qt视频流 4.3.2 qt搜索进程 5、成果呈现 6、问题解决 7、项目总结 1、项目背景 这个项目的背景是钢铁行业的…

从入门到精通:掌握Spring IOC/DI配置管理第三方bean的技巧

IOC/DI配置管理第三方bean 1.1 案例:数据源对象管理1.1.1 环境准备1.1.2 思路分析1.1.3 实现Druid管理步骤1:导入druid的依赖步骤2:配置第三方bean步骤3:从IOC容器中获取对应的bean对象步骤4:运行程序 1.1.4 实现C3P0管理步骤1:导入C3P0的依赖步骤2:配置第三方bean步骤3:运行程…

100:ReconFusion: 3D Reconstruction with Diffusion Priors

简介 官网 少样本重建必然导致nerf失败&#xff0c;论文提出使用diffusion模型来解决这一问题。从上图不难看出&#xff0c;论文一步步提升视角数量&#xff0c;逐步与Zip-NeRF对比。 实现流程 Diffusion Model for Novel View Synthesis 给定一组输入图像 x o b s { x i…

12.HTML5新特性

HTML5新特性 1.介绍 它是万维网的核心语言、标准通用标记语言下的一个应用超文本标记语言&#xff08;HTML&#xff09;的第五次重大修改。用于取代 HTML4 与 XHTML 的新一代标准版本&#xff0c;所以叫HTML5 HTML5 在狭义上是指新一代的 HTML 标准&#xff0c;在广义上是指…

浮动的魅力与挑战:如何在前端设计中巧妙运用浮动(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

FFmpeg的AVcodecParser

文章目录 结构体操作函数支持的AVCodecParser 这个模块是AVCodec中的子模块&#xff0c;专门用来提前解析码流的元数据&#xff0c;为后面的解码做准备&#xff0c;这一点对cuda-NVdec非常明显&#xff0c;英伟达解码器的元数据解析是放在CPU上的&#xff0c;所以就非常依赖这个…

对于初学者来说,从哪些方面开始学习 Java 编程比较好?

对于初学者来说&#xff0c;从哪些方面开始学习 Java 编程比较好&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「Java的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全…

react Hooks(useRef、useMemo、useCallback)实现原理

Fiber 上篇文章fiber简单理解记录了react fiber架构&#xff0c;Hooks是基于fiber链表来实现的。阅读以下内容时建议先了解react fiber。 jsx -> render function -> vdom -> fiber树 -> dom vdom 转 fiber 的过程称为 recocile。diff算法就是在recocile这个过程…