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