嵌入式学习笔记(四)

LoadStore内存读写指令

单寄存器读写指令

指令码
----------------ldr : 从内存地址中读取数据到寄存器中,读4个字节的数据str : 将寄存器中的数据写到内存地址中,写4个字节的数据
------------------------------------------------------ldrh : 从内存地址中读取数据到寄存器中,读2个字节的数据strh : 将寄存器中的数据写到内存地址中,写2个字节的数据
---------------------------------------------------------ldrb : 从内存地址中读取数据到寄存器中,读1个字节的数据strb : 将寄存器中的数据写到内存地址中,写1个字节的数据
----------------------------------------------------------ld : Load   st : Store   r : Register   h : half   b : byte 
---------------------------------------------------------------指令格式
---------------
ldr/ldrh/ldrb   Rd, [Rm][Rm] : 将Rm寄存器中的数据当成内存的地址功能:将[Rm]指向的地址空间的数据读到Rd寄存器中int a = 100;int *p = &a;int b = *p;[Rm]   <==>  pldr Rd, [Rm]   <==>  b = *p;str/strh/strb   Rn, [Rm][Rm] : 将Rm寄存器中的数据当成内存的地址功能:将Rn寄存器中的值写到[Rm]指向的地址空间中int a = 100, b = 200;int *p = &a;*p = b;
-----------------------------------指令测试代码
-----------------------/* 7. 单寄存器操作指令 */ldr r0, =0x40000800   @ 准备地址ldr r1, =0x12345678   @ 准备数据@ 将r1寄存器中的值写到[r0]指向的地址空间中str r1, [r0]@ 将[r0]指向的地址空间中的数据读到R2寄存器中ldr r2, [r0]------------------------------------------单寄存器操作指令的其他用法
---------------------------------
ldr/ldrh/ldrb  Rn, [Rm, #offset_addr][Rm + offset_addr]指向的地址空间的数据读到Rn寄存器中,Rm寄存器中存储的内存地址不变ldr/ldrh/ldrb  Rn, [Rm], #offset_addr
---------------------------------------------------[Rm]指向的地址空间的数据读到Rn寄存器中,同时更新Rm寄存器中的地址,Rm = Rm + offset_addrldr/ldrh/ldrb  Rn, [Rm, #offset_addr]!
--------------------------------------------------------------[Rm + offset_addr]指向的地址空间的数据读到Rn寄存器中,同时更新Rm寄存器中的地址,Rm = Rm + offset_addr! : 更新地址以上三种不同的指令格式同样适用于str/strh/strb指令。-------------------------------------------------------------ldr r0, =0x40000800   @ 准备地址ldr r1, =0x11111111   @ 准备数据ldr r2, =0x22222222ldr r3, =0x33333333@ 将r1寄存器中的数据写到[R0+4]指向的地址空间中@ R0寄存器中的地址不变@ [0x40000804] = 0x11111111  r0 = 0x40000800str r1, [r0, #4]@ 将r2寄存器中的数据写到[r0]指向的地址空间中@ 同时更新r0寄存器的地址@ [0x40000800] = 0x22222222  r0 = 0x40000804str r2, [r0], #4@ 将r3寄存器中的数据写到[R0+4]指向的地址空间中@ 同时更新r0寄存器的地址@ [0x40000808] = 0x33333333  r0 = 0x40000808str r3, [r0, #4]!----------------------------------------------------------练习题:将0x12345678数据写到内存的0x40000800地址中,使用ldrb指令读取0x40000800地址中的数据,每次读1个字节,读取4次。将读取的4个字节的数据使用位运算的方式拼接得到0x12345678ldr r0, =0x40000800ldr r1, =0x12345678str r1, [r0]@ 使用ldrb方式读取单字节的数据@ r2 = 0x78  r3 = 0x56   r4 = 0x34  r5 = 0x12/*ldrb r2, [r0, #0]ldrb r3, [r0, #1]ldrb r4, [r0, #2]ldrb r5, [r0, #3]*//*ldrb r2, [r0], #1ldrb r3, [r0], #1ldrb r4, [r0], #1ldrb r5, [r0]*/ldrb r2, [r0, #0]!ldrb r3, [r0, #1]!ldrb r4, [r0, #1]!ldrb r5, [r0, #1]!@ 使用位运算进行数据的拼接/*mov r6, r5   @ r6 = 0x12orr r6, r4, r6, lsl #8orr r6, r3, r6, lsl #8orr r6, r2, r6, lsl #8*//*mov r6, r5, lsl #24orr r6, r6, r4, lsl #16orr r6, r6, r3, lsl #8orr r6, r6, r2*/mov r6, r5, lsl #24lsl r4, r4, #16add r6, r6, r4lsl r3, r3, #8add r6, r6, r3lsl r2, r2, #0add r6, r6, r2

多寄存器读写指令

指令码
-----------stm : 向内存地址中同时写入多个寄存器中的数据ldm : 将内存地址中的数据同时读到多个寄存器中st : Store   ld : Load   m : multi
-----------------------------------------------------------指令格式
--------------
stm Rm, {寄存器列表}Rm : Rm寄存器中的数据被当成一个内存地址看待功能:将寄存器列表中的所有寄存器中的数据写到Rm指向的内存地址的连续空间中ldm Rm, {寄存器列表}Rm : Rm寄存器中的数据被当成一个内存地址看待功能:将Rm指向的内存地址空间中连续的数据读到寄存器列表的每个寄存器中寄存器列表的书写格式:1. 如果寄存器列表中的寄存器编号连续使用“-”隔开;比如:{r1-r5}2. 如果寄存器列表中的寄存器编号不连续使用“,”隔开;比如:{r1,r3,r5}   {r1-r4,r6}3. 寄存器列表中的寄存器编号要求从小到大进行书写,不要从大到小书写比如:{r1-r5,r7}   ---> OK{r5-r1, r0}  ---> Error, 编译报错{r5,r4,r3,r2,r1}  ---> Ok, 但是编译器报警告--------------------------------------------------------指令测试代码
------------
ldr r0, =0x40000800   @ 准备地址ldr r1, =0x11111111   @ 准备数据ldr r2, =0x22222222ldr r3, =0x33333333ldr r4, =0x44444444ldr r5, =0x55555555@ 将r1-r5寄存器中的数据写到@ r0指向的连续的20字节内存空间中@ stm r0, {r1-r5}stm r0, {r5,r4,r3,r2,r1}@ 将r0指向的连续的20字节内存空间@ 的数据读到r6-r10寄存器中@ ldm r0, {r6-r9, r10}ldm r0, {r10,r9,r8,r7,r6}
--------------------------------------------不管寄存器列表中的寄存器的顺序如何书写,永远都是小编号的寄存器对应着低地址,大编号的寄存器对应着高地址。
---------------------------------------------------{r5-r1, r0}  ---> Error, 编译报错{r5,r4,r3,r2,r1}  ---> Ok, 但是编译器报警告

特殊功能寄存器读写指令

指令码
--------------对cpsr寄存器进行读写操作的指令msr : 将普通寄存器中的数据写到特殊功能寄存器cpsr中mrs : 将特殊功能寄存器cpsr中的数据写到普通寄存器中m : move  s : special r : register
--------------------------------------------------------------指令格式
----------------msr  cpsr, Rnmrs  Rd, cpsr-----------------------指令测试代码
--------------
/* 系统上电,处理器默认工作再SVC模式下,修改CPSR寄存器的M[4:0]位,切换到user模式下,SVC模式(0b10011) ---> User模式(0b10000)修改模式位的同时,要保证其他位不变 修改CPSR的值: 1101 0011 ---> 1101 0000*/@ 方式1:之间对CPSR寄存器进行赋值操作@ msr cpsr, #0xD0--------------------------------------------------------@ 方式2:使用位运算@ 1. 先将cpsr中的值读到普通寄存器中mrs r0, cpsr@ 2. 将普通寄存器中的[4:0]位清0bic r0, r0, #0x1F   @ and r0, r0, #(~0x1F) @ 3. 将普通寄存器中的[4:0]位写成0x10orr r0, r0, #0x10@ 4. 将普通寄存器中的值写到CPSR中msr cpsr, r0
-----------------------------------------------------------

栈操作指令

栈的种类
--------------增栈:压栈之后栈指针向高地址方向移动。
------------------------------------减栈:压栈之后栈指针向低地址方向移动。
-------------------------------------满栈:当前栈指针指向的栈空间中有有效的数据,要想在栈空间中压入数据,需要向移动栈指针指向一个空的空间,然后再压入数据。压入数据之后,栈指针指向的空间又有有效的数据。
----------------------------------------------------空栈:当前栈指针指向的栈空间中没有有效的数据,可以先压入数据,需要移动栈指针指向一个空的空间。此时栈指针指向的又是一个空的空间。
-----------------------------------------------------------------栈空间的操作方式
-----------------
栈空间的读写方式有4种:满增栈 :Full Ascending Stack满减栈 :Full Descending Stack空增栈 :Empty Ascending Stack 空减栈 :Empty Descending Stack
--------------------------------------栈空间操作指令
---------------满增栈操作指令:stmfa/ldmfa满减栈操作指令:stmfd/ldmfd空增栈操作指令:stmea/ldmea空减栈操作指令:stmed/ldmed
----------------------------------------------ARM处理器中默认采用的是满减栈。
--------------------------------------------栈空间操作指令的语法格式
-----------------------------
stmfd sp!, {寄存器列表}sp : sp中存放的是指向的栈空间的地址! : 压栈之后更新栈指针的地址功能:将寄存器列表中的每个寄存器中的数据压到SP栈指针指向的连续的栈空间。ldmfd sp!, {寄存器列表}sp : sp中存放的是指向的栈空间的地址! : 压栈之后更新栈指针的地址功能:将SP栈指针指向的连续的栈空间中的数据出栈到寄存器列表的每个寄存器中。寄存器列表的书写格式:1. 如果寄存器列表中的寄存器编号连续使用“-”隔开;比如:{r1-r5}2. 如果寄存器列表中的寄存器编号不连续使用“,”隔开;比如:{r1,r3,r5}   {r1-r4,r6}3. 寄存器列表中的寄存器编号要求从小到大进行书写,不要从大到小书写比如:{r1-r5,r7}   ---> OK{r5-r1, r0}  ---> Error, 编译报错{r5,r4,r3,r2,r1}  ---> Ok, 但是编译器报警告-------------------------------------------------------------指令测试代码
-----------------ldr sp, =0x40000820   @ 准备地址ldr r1, =0x11111111   @ 准备数据ldr r2, =0x22222222ldr r3, =0x33333333ldr r4, =0x44444444ldr r5, =0x55555555@ 压栈@ 将r1-r5寄存器中的数据压倒sp指向的连续的栈空间中,@ 同时更新sp中的地址 , sp = sp - 20stmfd sp!, {r1-r5}@ 出栈@ 将sp指向的栈空间的数据出栈到r6-r10寄存器中,@ 同时更新sp中的地址, sp = sp + 20ldmfd sp!, {r6-r10}
------------------------------------------------------
#include <stdio.h>void add_func()
{int a = 300, b = 400;int sum = a + b;  // 700
}int main(int argc, const char *argv[])
{int a = 100, b = 200;add_func();int sum = a + b;  // 300return 0;
}
-------------------------------------------
ldr sp, =0x40000820  @ 初始化栈指针mov r0, #3mov r1, #4bl add_funcadd r2, r0, r1   @ r2 = r0 + r1 = 0x7b stopadd_func:stmfd sp!, {r0-r1, lr}  @ 压栈保存现场mov r0, #5mov r1, #6bl sub_funcadd r3, r0, r1  @ r3 = r0 + r1 = 0xBldmfd sp!, {r0-r1, pc}  @ 出栈恢复现场@ mov pc, lrsub_func:stmfd sp!, {r0-r1}  @ 压栈保存现场mov r0, #10mov r1, #2sub r4, r0, r1		@ r4 = r0 - r1 = 0x8ldmfd sp!, {r0-r1}  @ 出栈恢复现场mov pc, lr

跳转指令

指令码:
----------------b : 不带返回值的跳转指令发生跳转时,不会自动的保存返回地址到LR寄存器中----------------------------------------------------------bl  : 带返回值的跳转指令发生跳转时,会自动保存返回地址到LR寄存器中
-------------------------------------------------------------指令格式
----------------------------------------------------------
b/bl{cond}   Label(标签)	@ 程序跳转到label标签下的第一条指令Label:		@ 可以理解为C语言的函数名asm code注:1. label标签可以看成函数名,表示函数的入口地址,及函数内的第一条汇编指令的地址2. 跳转指令的本质是修改PC寄存器的值, PC = Label3. b跳转指令的使用:有去无回就用b;比如:stop:@ asm codeb  stop4. bl跳转指令的使用:有去有回就用bl;比如:函数的调用-------------------------------------------------------指令测试代码
-------------------/* 6. 跳转指令 */@ 定义一个交换函数,交换两个寄存器的值mov r0, #15mov r1, #9@ 使用bl指令调用swap_func函数@ 1. 查看PC寄存器是否执行函数的第一条指令@ 2. 查看LR寄存器中是否保存返回地址bl swap_funcnopnop     @ 空指令,没有任何的意义,只是占位@ b stopldr pc, stopswap_func:eor r0, r0, r1eor r1, r0, r1eor r0, r0, r1mov pc, lr    @ 函数的返回stop: b stop 
----------------------------------------------------------跳转指令的实现的其他的方式
----------------------------------1. mov pc, lr	    @ 一般用于程序的返回2. ldr pc, =Label   @ pc = Label  等价于 b Label3. mov pc, #label   @ 不一定,Label不一定是一个立即数,一般不用
-----------------------------------------------------------------练习题:使用跳转指令,比较指令,条件码,减法指令求两个数的最大公约数
---------------------------------------------------------------------.text.global _start_start:mov r0, #9mov r1, #15loop:cmp r0, r1beq stopsubhi r0, r0, r1subcc r1, r1, r0b loopstop:b stop .end 

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

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

相关文章

nandgame中的控制单元(Control Unit)

关卡说明的翻译&#xff1a; 控制单元除了ALU指令之外&#xff0c;计算机还应支持数据指令。在数据指令中&#xff0c;指令值直接写入A寄存器。创建一个控制单元&#xff0c;根据指令I的高位执行数据指令或ALU指令&#xff1a;位 15 0 数据指令 1 ALU指令ALU指令 对于ALU指令&…

Grok-1开源革新:探索人工智能的新境界

Grok-1开源革新&#xff1a;探索人工智能的新境界 在科技发展的马拉松中&#xff0c;Elon Musk旗下的xAI公司稳步前进&#xff0c;推出了名为Grok-1的语言模型。这个巨型模型&#xff0c;作为目前参数量最大的开源人工智能语言模型&#xff0c;赋予了机器学习领域全新的活力。 …

C#学习笔记4:PC串口发送数据

今日继续我的C#学习之路&#xff0c;今日学习制作PC串口发送数据的窗口程序 串口是单片机上位机开发的重点&#xff0c;本文围绕做一个通过PC端串口发送数据的程序进行实践学习&#xff0c; 文章提供源码与解释、整体工程文件 目录 1、控件的选择与摆放&#xff1a; 2、程序设…

435. 无重叠区间(力扣LeetCode)

文章目录 435. 无重叠区间题目描述贪心算法解题思路&#xff1a; 435. 无重叠区间 题目描述 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 示例 1: 输入: intervals [[1,…

2024.3.26

实现闹钟 weiget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTimer> #include<QTime> #include<QTimerEvent> #include<QString> #include<QtTextToSpeech> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } Q…

计算机复试面试问答准备(未完)

目录 1、理解多态性2、怎么逆置⼀个链表3、顺序表和链表的区别4、树的存储结构5、什么是哈夫曼树&#xff1f;简述哈夫曼树的构造过程。介绍哈夫曼树的特性。6、哈夫曼编码的编码和解码过程7、图的遍历方式8、图的存储方式9、最小生成树10、迪杰斯特拉算法11、佛洛依德算法12、…

mysql刨根问底

索引&#xff1a;排好序的数据结构 二叉树&#xff1a; 红黑树 hash表&#xff1a; b-tree&#xff1a; 叶子相同深度&#xff0c;叶节点指针空&#xff0c;索引元素不重复&#xff0c;从左到右递增排序 节点带data btree&#xff1a; 非叶子节点只存储索引&#xff0c;可…

C语言经典例题(8) --- 进制A+B、网购、及格分数、最高分数、计算一元二次方程

文章目录 1.进制AB2.网购3.及格分数4.最高分数5.计算一元二次方程 1.进制AB 题目描述&#xff1a; 输入一个十六进制数a&#xff0c;和一个八进制数b&#xff0c;输出ab的十进制结果&#xff08;范围-231~231-1&#xff09;。 输入描述&#xff1a; 一行&#xff0c;一个十六…

不使用额外空间交换两个数

1) 算术x x y;y x - y;x x - y; 2) 异或x x^y;// 只能对int,char..y x^y;x x^y;x ^ y ^ x;加法和异或这两种方法都是用于交换两个数的值而不使用额外空间的方法。它们的适用类型如下&#xff1a; 加法方法&#xff1a; 适用于整数类型&#xff08;int、long、long lo…

C++对象的创建和使用

定义了类&#xff0c;就相当于定义了一个数据类型。类与int、char等数据类型的使用方法是一样的。可以定义变量&#xff0c;数组和指针等。使用类定义的变量通常称为该类的对象。 对象的定义格式如下&#xff1a; 类名 对象名; 1.对象访问其成员 对象通过"."访问它的…

[NCNN学习笔记]-4

1、前言 继续学习NCNN。本次学习binaryop和eltwise。 2、学习内容 2.1、binaryop binaryop是用来二元计算的op&#xff0c;先来看binaryop.h的中关于二元计算的定义&#xff0c;其中二元计算定义了如下操作。 enum OperationType {Operation_ADD 0,Operation_SUB 1,Oper…

垃圾回收:垃圾回收器

目录 垃圾回收器 评估GC的性能指标 7种典型的垃圾回收器 Serial回收器&#xff1a;串行回收 ParNew回收器&#xff1a;并行回收 Parallel回收器&#xff1a;吞吐量优先 CMS回收器&#xff1a;低延迟 G1回收器&#xff1a;区域化分代式 G1回收过程1-年轻代GC G1回收过程…

自信当众讲话:从紧张到自如的转变之路

自信当众讲话&#xff1a;从紧张到自如的转变之路 在人生的舞台上&#xff0c;当众讲话是每个人都可能面对的挑战。然而&#xff0c;对于许多人来说&#xff0c;站在众人面前讲话却是一件令人紧张甚至恐惧的事情。这种紧张感往往源于对自我能力的怀疑&#xff0c;对未知的恐惧…

PyTorch----torch.nn.Linear()函数

torch.nn.Linear是PyTorch中的一个模块&#xff0c;用于在神经网络中实现完全连接层。它表示输入张量的一个线性变换通过将它与一个权矩阵相乘并加上一个偏置项。 下面是torch.nn.Linear的语法: torch.nn.Linear(in_features, out_features, biasTrue)参数&#xff1a; in_f…

neo4j使用详解(二、cypher语法基础——最全参考)

1.简介 Cypher是一种声明式图数据库查询语言&#xff0c;它具有丰富的表现力&#xff0c;能高效地查询和更新图数据。具有以下特点&#xff1a; 是一种声明性模式匹配语言遵循SQL语法的语法是非常简单且人性化、可读的格式 语法详情请看博主其他博客&#xff1a; 一、cypher插…

JS——9大陷阱

一、警惕A>X>B写法 3>2>1 返回值为false&#xff08;原因&#xff1a;3>2为true&#xff0c;会默认转成数字1&#xff0c;1>1为false&#xff09; 1<4<3 返回值为true&#xff08;原因&#xff1a;1<4为true&#xff0c;会默认转成数字1&#xff…

Leetcode第35题:搜索插入位置

代码实现 class Solution:def searchInsert(self, nums: List[int], target: int) -> int:if target in nums:return nums.index(target)index0for num in nums:if target>num:index1else:nums.insert(index,target)breakreturn index解题思路:先判断target是否在nums中…

【简单随机抽样】

文章目录 什么是简单随机抽样&#xff1f;简单随机抽样的步骤简单随机抽样的优点简单随机抽样的缺点 什么是简单随机抽样&#xff1f; 简单随机抽样是指从总体中以相同的概率随机选择一定数量的样本单元组成样本的一种方法。它要求每个样本单元被抽中的机会是均等的。每一个样…

滴滴出行高级Node.js开发工程师笔试题2024

今天参加了一个滴滴出行的Node.js岗位面试&#xff0c;一面为腾讯视频面试&#xff0c;俩个面试官。面试官比较深入问一些你过去做个的项目&#xff0c;问你解决了哪些棘手的问题。 还有就是他们比较关注性能优化&#xff0c;会问你们现在项目的峰值QPS是多少&#xff0c;如何进…

ChatGPT之道:AI与编程的完美融合

ChatGPT无限次数:点击直达 ChatGPT之道&#xff1a;AI与编程的完美融合 引言 随着人工智能技术的发展&#xff0c;AI在各个领域都展现出了惊人的应用潜力。在编程领域&#xff0c;AI的应用也是愈发广泛。其中&#xff0c;ChatGPT作为一种基于大型神经网络的自然语言生成模型&…