teq指令,bne指令

转载于http://www.Sohu.com/a/74272814 _ 119709

. macro restore_user_regs

ldr r1,[sp,#S_PSR]

ldr lr,[sp,#S_PC]! @! 用于控制基地址索引中的最终新地址是否执行写回操作。

执行ldr后,sp将写入sp #S_PC基地址转换地址的新地址

msrspsr,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 .将1.ldr ip、[sp]、#4sp的内容保存在ip中,然后sp=sp 4;

ldr ip,[sp,#4]将新地址sp 4的内容保存在ip中,然后不更改sp的值

ldr ip,[sp,#4]! 将新地址的内容保存在ip中sp 4,然后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先这样记住,然后再添加,保存数据

之后放入EA先这样记住,然后放入数据,之后放入end add

先减少再保存软盘先这样记住,先减少first dec,保存数据

以后减少ED先这样记住,积累数据,以后减少end dec

然后记忆LDM,因为LDM是STM的反相弹出动作

因为是先加算后存储,所以后减后取FA的话就会取与STM相对应的数据,后减

因为之后进行加法运算并先保存,所以如果先减法运算再取EA的话,就会先与STM对应进行减法运算并取数据

因为先减少后保存,所以之后先取下软盘的话,就会取下与STM对应的数据,之后再追加

因为之后减少后先保存,所以先追加后取ED的话会先追加到与STM对应的前面,然后取数据

我想用以上的变态方式比较简单地记住这个指令

完整堆栈的堆栈指针指向最后写入的最后一个数据单元,而空堆栈的堆栈指针指向第一个可用单元。

降序堆栈之一在内存中反向增加,也就是说,从APP应用区域的末尾开始反向增加,升序堆栈在内存中正向增加

其他形式的简要说明命令的行为、含义分别为

IA后增加Increment After )、

IB预增加、

DA后减少Decrement After )、

数据库提前减少。

RISC OS使用传统的降序堆栈。 在使用符合APCS规范的编译器时,通常将堆栈指针APP到应用程序空间的

最后,使用FD 降序-完全定义)堆栈。 与高级语言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操作,同时恢复的寄存器中含有pcr15)寄存器,那么指令执行的同时cpu自动将spsr拷贝到cpsr中

如:在IRQ中断返回代码中[如下为ads环境下的代码

ldmfd {r4} //读取sp中保存的的spsr值到r4中

msr spsr_cxsf,r4 //对spsr的所有控制为进行写操作,将r4的值全部注入spsr

ldmfd {r0-r12,lr,pc}^//当指令执行完毕,pc跳转之前,将spsr的值自动拷贝到cpsr中

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 maskbytePSR[7:0])

x - extension field maskbytePSR[15:8])

s - status field maskbytePSR[23:16)

f - flags field maskbytePSR[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

—————————–

9.指令后缀和条件判断

上图)

EQ : 等于

NE : 不等

CS : 无符号>=

CC : 无符号<

MI : 负数

PL : 非负[>=0]

VS : 溢出

VC : 无溢出

HI : 无符号>

LS : 无符号<=

GE : 有符号>=

LT : 有符号<

GT : 有符号>

LE : 有符号<=

AL : 总是[默认]

对于汇编指令,可以参考linux内核的arch/arm目录,那里的汇编指令很丰富[gliethttp_20080603]

__CopyFromStart

; ldr r3, [r9],#4

; str r3, [r7], #4

; sub r8, r8, #4

ldrb r3, [r9], #1

strb r3, [r7], #1

sub r8, r8, #1

cmp r8, #0

bgt __CopyFromStart

b __JumpToBootImage

__JumpToBootImage

MOV pc, r0

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注