(1) 简单的无条件转移unconditional branch
B Next; 调转到Next
(2) 有条件跳转
MOV R0, #20
Next
SUBS R0, R0, #1
BNE Next
注意在IAR编辑器中,标号的起始位置在最左端,不能留空格。
(3)带链接转移(相当于子程序调用)
BL Next; branch to “Next” with link
在这种情况下用r14来保存r15的值,然后跳转到子程序处
[r14] ← [PC];
[PC] ← Next
例如
BL TESTBL
continue
TESTBL
MOV PC, LR
总结跳转如下:
跳转指令实现程序流程的跳转,ARM程序实现跳转的方法有:
使用专门的跳转指令
直接向程序计数器PC写入跳移位址值
通过向程序计数器PC写入跳转位址值,可实现4GB位址空间的跳转,结合MOV LR, PC等可保存返回位址值。ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB的位址空间的转移。
B{条件} 目标位址
B指令是简单的跳转指令,存储在转移指令中的实际值是相对当前PC值的一个偏移量,而不是绝对地址。为24位有符号数,左移2位后有符号扩充为32位,表示有效偏移为26位(前后32MB空间)
BL{条件} 目标位址
BL是带链接的跳转,寄存器r14保存PC的当前内容,可通过将r14内容重新载入PC而返回。类似于子程序调用。
BLX 目标位址
BLX指令从ARM指令集跳转到指令中所指定的目标位址,并将处理器的工作状态从ARM状态切换到Thumb状态,该指令同时将PC的当前内容
保存在r14中。当使用者使用ARM指令集而副程序使用Thumb指令集时,可通过BLX实现副程序的使用和处理器工作状态的切换。
BX{条件} 目标位址
BX指令跳转到指令所指定的目标位址,目标位址的指令既可以是ARM指令,也可以是Thumb指令。
MOV r0, #0 ;[r0] ← 0, clear r0
MOV r0, r1, LSL #4 ;[r0] ← [r1] *16
MOVNE r3, r2, ASR #5 ;IF Z=0 THEN [r3] ← [r2]/32
MOVS r0, r1, LSL #4 ;[r0] ← [r1] *16, update
MVN r0, #0 ;[r0] ← -1; then 1’s complement of 0 is 111…11
MVN r0, r0 ;[r0] ←[r0], complement the bits of r0
MVN r0, #0xF ;[r0] ← 0xFFFFFFF0
LDR r0, [r1]
STR r2, [r3]
LDR r0, [r1, #8] ;effective address = [r1]+8, r1 is unchanged
LDR r0, [r1, #8]! ;effective address = [r1]+8, [r1] ←[r1]+8
LDR r0, [r1],#8 ;effective address = [r1], [r1] ←[r1]+8
常见操作举例:
向量乘
s=A∙B=a1∙b1+a2∙b2+…+an∙bn
MOV r4, #0 ;累加器清零
MOV r5, #24 ;向量长度为24
ADR r0, A ; r0指向向量A的地址
ADR r1, B ; r1指向向量B的地址
Next
LDR r2, [r0], #4
LDR r3, [r1], #4
MLA r4, r2, r3, r4 ;r4 = r4 + r2*r3,为乘加指令
SUBS r5, r5,#1 ;decrement loop counter
BNE Next
字符串比较:比较两个16-byte的串
ADR r0, String1
ADR r1, String2
LDMIA r0, {r2-r5} ;get first 16-byte string in r2 to r5, 采用多寄存器寻址方
;式,一条指令可以完成多个寄存器值的般移
LDMIA r1, {r6-r9}
CMP r2, r6
CMPEQ r3, r7
CMPEQ r4, r8
CMPEQ r5, r9
BEQ Equal ;if final 4 same then strings are equal
NotEq
…. ;if end here then string not same
Equal
…
堆
栈是一种资料结构,按后进先出(First In Last Out,
FILO)的方式工作,使用一个称为堆栈指针的专用寄存器指示当前的操作位置,堆栈指针(SP,Stack
Pointer)总是指向堆栈顶。当堆栈指针指向最后压入堆栈的资料时,称为满堆栈(Full
Stack),而当堆栈指针指向下一个将要存放资料的空位置时,称为空堆栈(Empty
Stack)。根据堆栈的生成方式,分为递增堆栈(Ascending Stack)和递减堆栈(Descending
Stack),当堆栈由低位向高位址生成时,称为递增堆栈;当堆栈由高位址向低位址生成时,称为递减堆栈。组合起来,一共有满递增堆栈,满递减堆栈,空递
增堆栈和空递减堆栈。
子程序调用
SUB1
…
STMFD r13, (r0-r4, lr) ;保存working registers and link register
BL SUB2
…
…
LDMFD r13, (r0-r4, pc) ;restore working registers and return
…
SUB2
…
MOV pc, lr ; return (copy link register to PC)
子程序调用通过带链接的分支指令BL实现,其返回地址保存在R14(LR)中,如果子程序需要调用另外的一个子程序,则必须在R14(LR)被覆盖之前,将其保存在堆栈中。
ARM微处理器支持连续资料的载入/存储指令,可以一次将一片连续的记忆体单元和多个寄存器之间般移资料。连续载入指令用于将一片连续的记忆体中的资料般移到多个寄存器,连续资料存储指令则完成相反的操作。
LDM 连续资料载入指令
STM 连续资料存储指令
语法:
LDM(STM) {条件}{类型}基址寄存器{!},寄存器列表{^}
该指令的常见用途是将多个寄存器的内容入堆栈或出堆栈。类型为非堆栈型寻址或堆栈型寻址。
非堆栈型寻址方式有:
IA(Increment After) 基址寄存器在存取后才增加
IB(Increment Before)基址寄存器在存取前即增加
DA(Decrement After)基址寄存器在存取后才减少
DB(Decrement Before)基址寄存器在存取前即减少
堆栈型寻址类型
FD(Full Descending) 满递减
FA(Full Ascending)满递增
ED(Empty Descending)空递减
EA(Empty Ascending)空递减
堆栈指令范例
STMFD R13!, {R0, R4-R12, LR} ;将寄存器列表中的寄存器存入堆栈
LDMFD R13!, {R0, R4-R12, PC};将堆栈内容恢复到寄存器
基址寄存器不允许为R15,寄存器列表可以为R0~R14的任意组合。{!}
为可选尾码,若选用该尾码,则当资料般移完毕之后,将最后的地址写入到基址寄存器。否则,基址寄存器的内容不改变。{^}为可选尾码,当指令为LDM且寄
存器列表包含R15时,选用该尾码还表示除了正常的资料般移外,还将SPSR复制到CPSR;此外还表示传染或传出的是用户模式下的寄存器,而不是当前模
式下的寄存器。
阅读(1815) | 评论(0) | 转发(0) |