当前位置: 首页 > news >正文

ARM汇编记忆

CPSR寄存器

CPSR寄存器的高四位和低八位的作用:N[31]:负数标志位(可用于判断两个数大小)当汇编指令的执行结果为负数时,N位会被硬件置1,否则,N位被清0Z[30]:零标志位(用于判断两个数是否相等)当汇编指令的执行结果为0时,Z位会被硬件置1,否则,Z位被清0C[29]:进位标志位(发生在做加法时):当汇编指令的执行结果需要进位时,C位会被硬件置1,否则,C位被清0借位标志位(发生在做减法时):当汇编指令的执行结果需要借位时,C位会被硬件清0,否则,C位被置1V[28]:符号位(溢出标志位)当汇编指令的执行结果改变了符号位,V位会被硬件置1,否则,Z位被清0I[7]:IRQ使能位(IRQ模式屏蔽位)I = 0, IRQ模式使能(可以进入IRQ模式下)I = 1, IRQ模式屏蔽(无法进入IRQ模式下)F[6]:FIQ使能位(FIQ模式屏蔽位)F = 0, FIQ模式使能(可以进入FIQ模式下)F = 1, FIQ模式屏蔽(无法进入FIQ模式下)T[5]:状态位T = 0, 当前处于ARM状态(可以使用ARM汇编指令集)T = 1, 当前不处于ARM状态(无法使用ARM汇编指令集)M[4:0]:模式位

R0~R12是普通寄存器,SP、LR、PC、CPSR、SPSR寄存器是特殊功能寄存器

R13  sp栈指针寄存器的作用:用于保存栈区的一片地址空间(用于实现局部变量的效果)
R14  lr链接寄存器的作用:用于保存函数的返回地址
R15  pc程序计数寄存器的作用:用于保存下一条需要执行的汇编指令的地址
CPSR寄存器的作用:用于保存当前程序的状态SPSR寄存器的作用:用于备份当前程序的状态

操作指令格式

{opcode}{cond}{s}        Rd, Rn, oprand2_shifter|      |   |          |   |        | --------> 第二操作数,相当于右操作数|      |   |          |   |        | --------> 第二操作数可以是:|      |   |          |   |        |           1、立即数|      |   |          |   |        |           2、普通寄存器|      |   |          |   |        |           3、经过移位操作的寄存器|      |   |          |   |        ||      |   |          |   |  --------> 第一操作寄存器(只能是寄存器的编号),相当于左操作数|      |   |          |   ||      |   |          | ---------> 目标寄存器,用于存放汇编指令执行完的结果|      |   ||      |   | ---------> 汇编指令的状态位,当汇编指令+s时,当前汇编指令的执行结果会影响CPSR寄存器的高四位(NZCV位)|      |                汇编指令不+s时,当前汇编指令的执行结果不会影响CPSR寄存器的高四位(NZCV位)|      ||      | ----------> 汇编指令的条件码,用于让汇编指令有条件的执行,通常和cmp比较汇编指令一起用,如EQ相等、NE不相等、HI大于||  -----------> 汇编指令的指令码,如mov赋值指令码、b跳转指令码、cmp比较指令码注意:1、{opcode}{cond}{s}是连在一起写的,中间不允许出现空格、逗号2、Rd, Rn, oprand2_shifter是连在一起写的,中间通过英文下的,进行分隔3、{opcode}{cond}{s}   和    Rd, Rn, oprand2_shifter 这两个部分中间需要用空格隔开4、编写汇编指令时,一条汇编指令就占一行,不允许出现多条汇编指令在同一行的情况5、汇编指令没有大小写区分,如mov r0, #0xff   <------>    MOV R0, #0XFF    <------> MoV r0, #0xFF6、本次汇编文件使用到编译工具支持的注释方式:单行注释:@多行注释:/**/条件注释:.if 0    .else      .endif7、本次汇编文件中如果出现以.开头的指令,如.text .if .end .endif,这些都是伪指令,不是真正的汇编指令,不占用代码段的空间本次汇编文件中如果出现汇编指令,如mov r0, #0xff    b stop ,每条汇编指令占代码段空间的32位(4个字节)

清 '0'  置 '1' 

and    -----    按位与(&)     -----        与0清0,与1不变
orr    -----    按位或(|)     -----        或1置1,或0不变
eor    -----    按位异或(^)   -----        异或1取反,异或0不变
mvn    -----    按位取反(~)与 ' | ' 还可以用于追加

cmp比较指令相关条件码

无符号数:
等于    EQ
不等于    NE大于等于    CS
小于    CC大于    HI
小于等于    LS
有符号数:
等于    EQ
不等于    NE大于等于    GE
小于    LT大于    GT
小于等于    LE

跳转指令

b   有去无回bl  有去有回  回到lr里面
(多次跳转要回 注意也要 对lr寄存器 也进行压栈出栈 操作)

左移右移

lsl  左移(无符号数)lsr  右移(无符号数)ror  循环右移asr  算术右移

写入 读取  (对地址进行操作)

ldr    ------    从内存空间中读取4个字节的数据
ldrh   ------    从内存空间中读取2个字节的数据
ldrb   ------    从内存空间中读取1个字节的数据str    ------    向内存空间中写入4个字节的数据
strh   ------    向内存空间中写入2个字节的数据
strb   ------    向内存空间中写入1个字节的数据   ld:load(加载)    st:store(存储)    r:register(4个字节)    h:half word(2个字节)  
b:byte(1个字节)    word:一个字(4个字节)
ldr/ldrh/ldrb Rd, [Rn, #offset]
解释:将Rn+#offset看作是一片内存空间地址从Rn+#offset这片内存空间地址中读取4个字节/2个字节/1个字节的数据到Rd寄存器中注意:此时,Rn寄存器中的值不变ldr/ldrh/ldrb Rd, [Rn], #offset
解释:将Rn看作是一片内存空间地址从Rn这片内存空间地址中读取4个/2个/1个字节的数据到Rd寄存器中注意:此时,读取完数据后,Rn这篇内存空间地址发生偏移,Rn寄存器中的值 = Rn + #offsetldr/ldrh/ldrb Rd, [Rn, #offset]!
!的作用:实时更新地址空间的值
解释:将Rn+#offset看作是一片内存空间地址从Rn+#offset这片内存空间地址中读取4个/2个/1个字节的数据到Rd寄存器中注意:在读取数据的同时,Rn这片内存空间就发生了地址偏移,Rn寄存器中的值 = Rn + #offset注意:1、#offset就是内存地址的偏移量,就是一个数字2、str/strh/strb和上述操作格式一致,只是将指令码改变了,也就是从读取操作变为写入操作3、使用ldr/str操作内存空间时,#offset偏移量必须要是4的倍数4、使用ldrh/strh操作内存空间时,#offset偏移量必须要是2的倍数5、使用ldrb/strb操作内存空间时,#offset偏移量必须要是1的倍数

对sp寄存器进行操作

压栈(写入)stmfd  sp!,  {r1-r4,r6,lr}写入时 栈指针先向低地址移动 再写入数据出栈(读取)ldmfd  sp!,  {r1-r4,r6,pc}读取时 栈指针的指向向高地址移动注:将lr传入pc 相当于 mov  pc, lr
(有跳转需要返回时<使用bl指令时>注意lr寄存器内值的变化)
增栈:进行压栈操作时,栈指针会向地址高位的方向移动进行出栈操作时,栈指针会向地址低位的方向移动减栈:进行压栈操作时,栈指针会向地址低位的方向移动进行出栈操作时,栈指针会向地址高位的方向移动满栈:当前栈指针指向的空间内存在有效数据如果需要进行压栈操作,需要先移动栈指针的指向,再进行压栈操作空栈:当前栈指针指向的空间内没有有效数据如果需要进行压栈操作,可以直接压入数据,再移动栈指针的指向栈的分类:满减栈(Full Descending Stack)    -------> ARM架构使用的是满减栈满增栈(Full Ascending Stack)空减栈(Empty Descending Stack)空增栈(Empty Ascending Stack)

对CPSR的操作

# 指令只有 msr 和 mrs
msr   CPSR, Rn
解释:将Rn寄存器中的值写入到CPSR寄存器中mrs   Rd, CPSR
解释:从CPSR寄存器中读取数据到Rd寄存器中注意:之前学习的汇编指令无法操作CPSR寄存器中,只有msr和mrs可以操作CPSR寄存器
举例:
/***********************10、CPSR特殊功能寄存器指令**************************/@ 已知CPSR寄存器中的值为0xD3(正常情况下,我们并不知道CPSR寄存器中具体是什么值)@ 目的:我们需要将当前工作模式从SVC模式切换到User模式@ 我们只可以改变CPSR寄存器中的M[4:0]位,其他的位是不可以改变的@ 此时,需要用于位运算相关的汇编指令/*问题:普通的汇编指令无法直接操作CPSR寄存器,需要通过MSR和MRS这条湖边指令来操作CPSR寄存器and CPSR, CPSR, #(~(0x1f << 0))orr CPSR, CPSR, #(0x1 << 4)*//*1、可以先使用mrs将CPSR寄存器中的值读取到普通寄存器中2、再通过and和orr修改普通寄存器中的值3、将修改完的值通过msr写入到CPSR寄存器中SVC模式(10011)  ----->   User模式(10000)*/mrs r0, cpsrand r0, r0, #(~(0x1f << 0))orr r0, r0, #(0x1 << 4)msr cpsr, r0@ 不推荐这样写,由于你并不清楚CPSR寄存器中具体是什么值@ msr cpsr, #0xd0

http://www.dtcms.com/a/362589.html

相关文章:

  • 【53页PPT】华为制造行业数字化转型工业互联网智能制造解决方案(附下载方式)
  • MySQL事务+MVCC(精简版,包教包废)
  • 2025华为最值得入的耳机,真的赢麻了!
  • 结构抗震与土木工程研究
  • SylixOS 下的信号系统
  • Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
  • Chrome浏览器调用ActiveX控件之allWebOffice在线编辑控件
  • JD潜在前端二面高频题解析
  • mysql5.6+分页时使用 limit+order by 会出现数据重复问题
  • 蓝桥杯算法之基础知识(5)
  • 基于Spark的新冠肺炎疫情实时监控系统_django+spider
  • 数据结构与算法个人学习代码笔记包含leetcode,海贼oj,蓝桥杯,ACM
  • 华为Fit4:腕间助手,守护你的健康,带你开启智慧生活
  • 【字节拥抱开源】 UXO 团队开源 USO: 通过解耦与奖励学习实现的统一风格与主题驱动生成
  • 2025最新“Java 面试八股文 + 各大厂的面试真题”限时开源
  • 美团 LongCat 开源大模型60 亿参数 MoE 架构,赋能开发者加速 AI 应用落地
  • 本地搭建并使用 Redmine 详细教程
  • CICD 持续集成与持续交付
  • SGLang推理引擎--高效的开源部署方案
  • 【第四章:大模型(LLM)】09.最强开源大模型:Llama3 原理介绍与实现-(6)Llama2 Llama3代码实现
  • Wifi开发上层学习1:实现一个wifi搜索以及打开的app
  • 零依赖每月工作计划备忘录:高效管理你的每一天
  • Qt 创建的C++ 桌面程序 学习笔记1
  • Elasticsearch创建索引分片和副本大小建议
  • iOS XML 处理利器:CNXMLParser 与 CNXMLDocument 深度解析
  • iOS15如何绕过MDM锁?详细图文教程教你搞定
  • 数据结构:基数排序 (Radix Sort)
  • uni-app iOS 性能监控与调试全流程:多工具协作的实战案例
  • Qt中QSettings的键值使用QDataStream进行存储
  • 【Vue2 ✨】Vue2 入门之旅(七):事件处理