macro restore_user_regs
ldr r1,[sp, #S_PSR]
ldr lr,[sp, #S_PC]! @ !用来操控基址变址寻址的终究新地址是否进行回写操作,
@ 履行ldr之后sp被回写成sp+#S_PC基址变址寻址的新地址
msr spsr,r1 @ 把cpsr的值保存到spsr中
ldmdb sp,{r0 – lr}^ @ lr=[sp-1*4],r13=[sp-2*4],r12=[sp-3*4],……,r0=[sp-15*4]
@ 由于没对pc赋值,所以^的表明将数据康复到User方法的[r0-lr]寄存器组中[gliethttp]
mov r0,r0
add sp,sp,#S_FRAME_SIZE – S_PC
movs pc,lr
.endm
其他指令正在学习中[随时弥补gliethttp]
—————————–
1.ldr ip,[sp],#4 将sp中内容存入ip,之后sp=sp+4;
ldr ip,[sp,#4] 将sp+4这个新地址下内容存入ip,之后sp值坚持不变
ldr ip,[sp,#4]!将sp+4这个新地址下内容存入ip,之后sp=sp+4将新地址值赋给sp
str ip,[sp],#4 将ip存入sp地址处,之后sp=sp+4;
str ip,[sp,#4] 将ip存入sp+4这个新地址,之后sp值坚持不变
str ip,[sp,#4]!将ip存入sp+4这个新地址,之后sp=sp+4将新地址值赋给sp
—————————–
2.movs r1,#3 ;movs将导致ALU被更改,由于r1赋值非0,即操作成果r0非0,所以ALU的Z标志清0
bne 1f ;由于Z=0,阐明不等,所以向前跳到标号1:地点处持续履行其他句子
—————————–
3.LDM表明装载,STM表明存储.
LDMED LDMIB 预先添加装载
LDMFD LDMIA 往后添加装载
LDMEA LDMDB 预先削减装载
LDMFA LDMDA 往后削减装载
STMFA STMIB 预先添加存储
STMEA STMIA 往后添加存储
STMFD STMDB 预先削减存储
STMED STMDA 往后削减存储
留意ED不同于IB;只关于预先削减装是相同的.在存储的时分,ED是往后削减的.
FD、ED、FA、和 EA 指定是满栈仍是空栈,是升序栈仍是降序栈.
关于存储STM而言
先加后存 FA 权且这么来记,先加(first add),存数据
后加先存 EA 权且这么来记,存数据,后加end add
先减后存 FD 权且这么来记,先减first dec,存数据
后减先存 ED 权且这么来记,存数据,后减end dec
然后回忆LDM,LDM是STM的反相弹出动作,所以
由于是先加后存,所今后减先取 FA 就成了与STM对应的取数据,后减
由于是后加先存,所以先减后取 EA 就成了与STM对应的先减,取数据
由于是先减后存,所今后加先取 FD 就成了与STM对应的取数据,后加
由于是后减先存,所以先加后取 ED 就成了与STM对应的先加,取数据
我想通过上面的反常方法能够比较简略的记住这套指令[gliethttp]
一个满栈的栈指针指向前次写的最终一个数据单元,而空栈的栈指针指向第一个闲暇单元.
一个降序栈是在内存中反向添加(就是说,从应用程序空间结束处开端反向添加)而升序栈在内存中正向添加.
其他方法简略的描绘指令的行为,意思别离是
IA往后添加(Increment After)、
IB预先添加(Increment Before)、
DA往后削减(Decrement After)、
DB预先削减(Decrement Before).
RISC OS运用传统的满降序栈.在运用契合APCS规则的编译器的时分,它一般把你的栈指针设置在应用程序空间的结束处并接着运用一个FD(满降序-Full Descending)栈.假如你与一个高档言语(BASIC或C)一同作业,你将别无选择.
栈指针(传统上是R13)指向一个满降序栈.你有必要持续这个格局,或则树立并办理你自己的栈.
4.teq r1,#0 //r1-0,将成果送入状况标志,假如r1和0相减的成果为0,那么ALU的Z置位,不然Z清0
bne reschedule//ne表明Z非0,即:不等,那么履行reschedule函数
—————————–
5.运用tst来查看是否设置了特定的位
tst r1,#0x80 //按位and操作,检测r1的0x1<<7,即第7位是否置1,按位与之后成果为0,那么ALU的Z置位
beq reset //假如Z置位,即:以上按位与操作成果是0,那么跳转到reset标号履行
—————————–
6.^的了解
^是一个后缀标志,不能在User方法和Sys体系方法下运用该标志.该标志有两个存在意图:
6.1.关于LDM操作,一起康复的寄存器中含有pc(r15)寄存器,那么指令履行的一起cpu主动将spsr拷贝到cpsr中
如:在IRQ中止回来代码中[如下为ads环境下的代码gliethttp]
ldmfd {r4} //读取sp中保存的的spsr值到r4中
msr spsr_cxsf,r4 //对spsr的一切操控为进行写操作,将r4的值悉数注入spsr
ldmfd {r0-r12,lr,pc}^//当指令履行结束,pc跳转之前,将spsr的值主动拷贝到cpsr中[gliethttp]
6.2.数据的送入、送出产生在User用户方法下的寄存器,而非当时方法寄存器
如:ldmdb sp,{r0 – lr}^;表明sp栈中的数据到User分组寄存器r0-lr中,而不是康复到当时方法寄存器r0-lr 当然关于User,System,IRQ,SVC,Abort,Undefined这6种方法来说[gliethttp]r0-r12是共用的,只是r13和r14
为别离独有,关于FIQ方法,只是r0-r7是和前6中方法的r0-r7共用,r8-r14都是FIQ方法下专有.
7.spsr_cxsf,cpsr_cxsf的了解
c - control field mask byte(PSR[7:0])
x - extension field mask byte(PSR[15:8])
s - status field mask byte(PSR[23:16)
f - flags field mask byte(PSR[31:24]).
旧式声明方法:cpsr_flg,cpsr_all在ADS中现已不在支撑
cpsr_flg对应cpsr_f
cpsr_all对应cpsr_cxsf
需求运用专用指令对cpsr和spsr操作:mrs,msr
mrs tmp,cpsr //读取CPSR的值
bic tmp,tmp,#0x80 //假如第7位为1,将其清0
msr cpsr_c,tmp //对操控位区psr[7:0]进行写操作
—————————–
8.cpsr的了解
CPSR = Current Program Status Register
SPSR = Saved Program Status Registers
CPSR寄存器(和保存它的SPSR寄存器)
N,Z,C,V称为ALU状况标志
N:假如成果是负数则置位
Z:假如成果是零则置位
C:假如产生进位则置位
V:假如产生溢出则置位
I:置位表明禁用IRQ中止,清0表明使能IRQ
F:置位表明禁用FIQ中止,清0表明使能FIQ
T:置位表明体系运行在Thumb态,清0表明运行在ARM态
M[4:0]:
10000 User方法,和System体系方法相同
10001 FIQ方法
10010 IRQ方法
10011 SVC超级办理方法
10111 Abort数据反常方法
11011 Undefined未定义指令方法
11111 System体系方法,和User方法相同
举例:
ands r2,r2,#7 运用运算成果改动标志位,假如运算成果r2=0,那么Z置位,EQ持平判别建立
subs r2,r2,#1 运用运算成果改动标志位,假如运算成果r2=0,那么Z置位,EQ持平判别建立
beq wordcopy
EQ : 等于
NE : 不等
CS : 无符号>=
CC : 无符号<
MI : 负数
PL : 非负[>=0]
VS : 溢出
VC : 无溢出
HI : 无符号>
LS : 无符号<=
GE : 有符号>=
LT : 有符号<
GT : 有符号>
LE : 有符号<=
AL : 总是[默许]