希望本是无所谓有,无所谓无的,这正如脚下的路,其实地上本没有路,走的人多了,也便成了路....原创不易,文章会持续更新,感谢您的关注

1.伪指令和指令之间的差别

指令是CPU机器码的助记符,它经过编译后会实实在在的在CPU中执行;而伪指令本质上不是指令,它是编译环境提供的,目的是指导编译过程,汇编指令经过汇编器编译之后就会消失,不会出现在机器码中。

2.两种编程风格

windows下的IDE工具(譬如:MDK或是ADS),在这种环境下,汇编指令一般是大写;另一种就是GNU环境下的,指令一般是小写;当然最主要区别还是在于伪指令有很多的不同,因为伪指令是编译环境提供的。

3.arm汇编指令的特点

(1)arm汇编指令特点1:ldr/str架构
因为arm CPU采用RISC架构,这种架构下的CPU内核是不能直接和内存通信,即CPU是不能直接访问内存的。

必须先将内存中的数据加载到那37个通用寄存器中,CPU可以直接访问这些寄存器,然后再在寄存器中处理数据,处理完成之后再将数据写回到内存中。内存中的数据加载到通用寄存器,就是ldr;将寄存器中的数据写回到内存中就是str;所以arm CPU采用的就是这种ldr-str架构。

(2)特点2:有8中寻址方式(2.1)寄存器寻址:mov r0, r1;指寄存器之间的访问,将寄存器r1中的内容加载到r0寄存器中。

(2.2)立即数寻址:mov r0, #0xff00;将一个立即数放到r0。什么是立即数?因为在计算机中所有的信息都是二进制数据,不管是图片还是文字,当然数字也是二进制的。为了能够更加详细的表示一个二进制数据本身就是一个数字,所以将这个数字的二进制或是十六进制称为立即数;譬如0x1200ff是一个二进制数,但是我们也无法知道它是真正的数字还是文字或是图片,在这个数据的前面加上一个#就表示,它是一个实实在在的数字,也就是立即数。

(2.3)寄存器移位寻址:mov r1, r0, lsl #3;先将r0中的数据左移3位,然后再移到r1。

(2.4)寄存器间接寻址:ldr r0,[r1];加上一个[ ]之后,表示r1里面放的是一个内存地址。这句代码的意思:将以r1中存放的数为内存的内容加载到r0。

(2.5)基址变址寻址:ldr r0,[r1, #4];将以r1中的数+4为内存地址处的内容放到r0寄存器中;r1中的数值就相当于基址,#4就相当于变址。

(2.6)多寄存器寻址:ldmia r1!,{r2~r7,r12} ;ldr指将内存中数据加载到寄存器中,这里指将r1中的数字作为内存的基地址,从这个基地址开始依次将内存数据加载到r2~r7和r12中;每加载一个寄存器后,r1的值就是自动的+4。

(2.7)堆栈寻址:stmfd sp!, {r2 ~ r7, lr} ;sp是一个堆栈指针,str表示将寄存器中的数据加载到内存中,这里就是r2~r7和lr这些寄存器的值加载到以sp中的数字为基地址的堆栈中。

(2.8)相对寻址:bl flag ;flag是一个标号,表示某个指令的地址,使用bl直接跳转到这个标号处去执行代码。

(3)指令后缀,加上指令后缀不会改变这条指令的基本功能

(3.1)b(byte):默认情况下arm指令操作的都是32位的数据,访问内存时也是这样。在访问内存指令的后面加上一个b表示操作数为8位,也就是一次只访问8位的数据,而不是32位的数据。

(3.2)h(helf word):表示操作的数据长度是16位,其他和上面的一样。

(3.2)s(s标志):默认情况下指令运行的结果是不会影响cpsr寄存器中的标志位的。

(4)条件执行
譬如:moveq r1,r0 这条指令是否执行取决于前面的指令(可能就是上一条指令,也可能是前好几条指令)的运行结果。如果前面的指令的运行结果影响了cpsr寄存器中的标志位,并且影响的标志位符合这个指令的后缀,那么这条指令就会执行,否则就不会执行。譬如eq的含义就是标志位Z是否等于1,若等于1就会执行这条指令,如果不等于1,就会直接跳过,不会执行这条指令。

(5)多级流水线机制:
原理不用明白,只要知道,流水线机制造成的结果就是:PC寄存器中的值不是当前正在执行的指令的地址,而是当前正在执行的指令的地址+8地址处的指令。当我们函数调用或是异常处理时,PC中保存的值不是下一条的地址,而是下一条指令的地址 + 8,所以你在返回时放到PC的地址要lr - 8。

4.ARM数据处理指令

(1) mov(将立即数移动到寄存器中)、add、sub。
(2)bic:可以将数据的特定位清零,譬如:bic r1,#0x008:将r1寄存器中数据的第4位清0。
(3)orr:逻辑或。
(4)and:逻辑与。
(5)eor:逻辑异或。

5.ARM比较指令

比较指令默认就是会影响标志位的(即使不在后面加上s也会影响对应的标志位)。

(1)cmp:比较两个数据是否相等。如果相等,就将cpsr寄存器中的对应标志位置1,如果后面的指令有条件后缀,那么这条带条件的指令就会根据cpsr对应的标志位是否满足自己的要求来选择是否执行当前这句代码。cmp的本质就是将这两个数相减,然后看结果是否为0。

(2)cmn(用得不多):也是用来比较两个数的,cmp使用的比较方式是让这两个数据进行相减;这里的比较方式是让两个数相加,然后看相加后的数据是否为0,如果为0就会影响cpsr中的对应标志位。

6.ARM cpsr访问指令

因为cpsr寄存器比较特殊,所以需要专门的mrs和msr指令来进行访问。mrs用来读cpsr寄存器,将cpsr寄存器中的值读到某个通用寄存器中;msr就是将通用普通寄存器中的数据写到cpsr中。

7.ARM跳转指令

(1)b:直接跳转到标号处,不会返回。
(2)bl:在跳转到标号处之前,会先将PC寄存器中的值放到lr寄存器中(这是CPU自动做的,不用程序员来操作),然后再跳转到标号处去执行代码,执行完毕后,再返回到原来的位置继续执行代码。

8.ARM内存访问指令

(1)ldr:将内存中的数据加载到寄存器中。
(2)str:将寄存器中数据写到内存中。
(3)ldm:批量处理指令,在前面有介绍。
(4)stm:同理,批处理指令。

9.ARM swi软中断指令

CPU只要一执行这条指令就会触发一次中断(也就是跳转到对应的异常向量表中去执行对应的处理函数),因为这种中断是通过软件来产生的而不是硬件,所以被称为软中断。

10.ARM批量处理指令

ldr/str每个周期只能访问四个字节内存,如果需要批量读写操作数效率就太低了,所以就有了ldm/stm。批量处理的过程也是一个时钟周期,即一个时钟周期就能完成批量处理。使用ldr读四个字节需要一个时钟周期,使用ldm批量读取多个内存字节也是只需要一个时钟周期,使得效率得以提升。

stmia sp,{r0~r12}:sp寄存器中的值为内存地址,将该地址中的内容写到r0中,然后sp的地址值加4后,再将该地址的数据写到r1中,依次类推即可。虽然这一条指令处理的东西有点复杂,但是也同样只要一个时钟周期就可以完成。

11.特殊符号的作用

(1)!,感叹号的作用ldmia r0,{r2~r3} ;r0寄存器中的值为内存地址,将该地址中的内容写到r2中,然后r0地址+4,接着将内存中的内容放到r3。有个关键的地方,就是每次地址在加4的时候,sp中的值没有变。这句指令不会修改sp中的值。

ldmia r0!,{r2~r3} ;这句代码和上面的一样;区别就在于,每次地址就加4之后,会同时将这个加4之后的地址赋回给sp中,即sp中的值是不停的在变的。

(2)^符号的作用ldmfd sp!,{r0-r6,pc}和ldmfd sp!,{r0-r6,pc}^ ;^的作用:在目标寄存器中有pc时,会同时将spsr写入到cpsr。

12.8种批处理指令后缀

(1)Ia:先传输,再地址加4
(2)Ib:先地址加4,然后再传输
(3)da:先传输,再地址减4
(4)db:先地址减4,再传输
(5)fd:满减栈
(6)ed:空减栈
(7)fa:满增栈
(8)ea:空增栈

13.四种栈模型

(1)空栈:栈指针指向空处,每次都可以将数据直接写入栈中,然后自己再将栈指针移动一格;而取出数据的时候,要先移动一格栈指针,然后才能取数据。

(2)满栈:栈指针指向最后一格数据,每次存入数据之前都要先将栈指针移动一格,然后再存入;当取数据的时候就可以直接取。

(3)增栈:每次移动栈指针时,栈指针是加4。

(4)减栈:每次移动栈指针时,都是减4。

注: 批处理指令后缀和四种栈模型有对应关系。ARM默认使用的是满减栈(fd)。即stmia和stmfd

专注于 嵌入式qt知识分享

欢迎扫码关注
“嵌入式工程师成长之路”

汇编指令mrs_专题1:电子工程师 之 软件】 之 【8.arm指令】相关推荐

  1. 为什么在中国电子工程师不如搞软件的?

    知乎用户:时光行者 做了9年硬件电路设计,5年智能手机,4年医疗器械,看到这个问题,心情很复杂,自己喜爱的工作居然无奈的发展到了这个窘境. 当初选择硬件是因为不想日复一日的坐在屏幕前面敲代码到天亮,硬 ...

  2. ARM指令寻址方式及RealView MDK开发环境ARM汇编程序实践

    内容简介 本文根据作者在CSDN发表的树莓派ARM汇编语言编程十讲(第3讲) (CSDN链接https://blog.csdn.net/yuanzywhu/article/details/104975 ...

  3. arm 指令 学习载录

    ARM处理器汇编 ARM寻址方式: 1. 立即寻址,操作数在指令中给出. ADDR0,R0,#1;    R0ßR0+1 ANDR8,R7,#&FF; R8ßR7[7:0]; ADDR0,R0 ...

  4. Arm指令模拟器开发参考指南【翻译自 armDeveloper】

    目录 简介 开始 安装ARMIE 安装之前 安装步骤 安装之后 开始使用ARM 指令模拟器 开始之前 步骤 示例:编译并执行一个"Hello World"程序 示例:编译,向量化和 ...

  5. thumb指令和arm指令

    参考https://www.embedded.com/introduction-to-arm-thumb/ 一.为什么一个芯片需要thumb和arm两套指令集 许多复杂的功能在复杂指令集(CISC)处 ...

  6. ARM指令和Thumb指令的区别

    一.现在先区分下ARM指令集与Thumb指令集        Thumb 指令可以看作是 ARM 指令压缩形式的子集,是针对代码密度的问题而提出的,它具有 16 位的代码密度但是它不如ARM指令的效率 ...

  7. 汇编指令mrs_汇编指令 - Mrs.kang - 博客园

    1.debug的常用命令 1.r命令 查看.修改CPU中寄存器的值 -r :查看寄存器的值 -r  cs :修改寄存器cs的值 2.D命令 查看内存中的内容 1.-d  段地址:偏移地址 -d 100 ...

  8. 转载 电子工程师的程序人生历程

    电子工程师的程序人生历程 这些日子我一直在写一个实时操作系统内核,已有小成了,等写完我会全部公开,希望能够为国内IT的发展尽自己一份微薄的力量.最近看到很多学生朋友和我当年一样没有方向 ,所以把我的经 ...

  9. 合格的电子工程师需要掌握的知识和技能

    合格的电子工程师需要掌握的知识和技能   (转载) 愚以为,掌握了一下的硬件和软件知识,基本上就可以成为一个合格的电子工程师:   第一部分:硬件知识    一. 数字信号    1. TTL和带缓冲 ...

最新文章

  1. anconda安装及opencv配置
  2. linux tcp cork,在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异?
  3. linux中的特殊文件权限
  4. html新增的选择器,HTML5新增的选择器
  5. Git异常:fatal: could not create work tree dir 'XXX': No such file or directory
  6. junit5 动态测试_JUnit 5嵌套测试
  7. VB.NET 网络通讯示例(服务端)
  8. win10系统下第三方软件字体大小调整
  9. 华硕h410csm怎么开启_华硕主板怎么开启uefi模式?华硕主板BIOS开启uefi模式详细方法...
  10. 初写数学建模论文 -- 摸鱼1
  11. 国外广告联盟,别被人当傻子割了
  12. Android 监听短信2种方式:Broadcast和ContentObserver
  13. 7zip打不开wim文件
  14. PicPick软件系统语言设置
  15. 如何理解光圈、ISO、快门、曝光这几个概念?
  16. 理解Fourier变换,Laplace变换和Z变换的几个基本点
  17. Wayland utilizing Android GPU drivers on glibc based systems, Part 1
  18. C51学习笔记 7.LED点阵屏
  19. 安卓下Kindle导入本地电子书的方法
  20. 自动驾驶中车辆3Dbox检测相关论文

热门文章

  1. 插图 引用 同一行两个插图_数学身份的优雅LED插图
  2. python seaborn heatmap可视化相关性矩阵
  3. 2010年高教社杯全国大学生数学建模竞赛题目B题解析及层次分析法AHP在其中的应用
  4. Python编写俄罗斯方块小游戏
  5. 盘点 Python 高手都写不出来的几个错误
  6. Python高级——用多线程实现UDP聊天器
  7. Python2.7.16安装(Win10)
  8. 深度学习与计算机视觉系列(3)_线性SVM与SoftMax分类器--在深度学习的视觉分类中的,这两个分类器的原理和比较
  9. Hadoop较全面的概述
  10. 漫步线性代数十二——网络