这个程序用批量传输指令传输数据,一次可传8个字:
AREA Block, CODE,
READONLY
; name this block of code
num
EQU
20
; Set number of words to be copied
ENTRY
; mark the first instruction to call
start
LDR
r0,
=src
; r0 = pointer to source block
LDR
r1,
=dst
; r1 = pointer to destination block
MOV
r2,
#num
; r2 = number of words to copy
MOV
sp,
#0x400
; set up stack pointer (r13)
blockcopy
MOVS r3,r2,
LSR #3 ; number of eight word
multiples
BEQ
copywords
; less than eight words to move ?
STMFD sp!,
{r4-r11} ; save some working
registers
octcopy
LDMIA r0!,
{r4-r11} ; load 8 words from
the source
STMIA r1!,
{r4-r11} ; and put them at the
destination
SUBS r3, r3,
#1
; decrement the counter
BNE
octcopy
; ... copy more
LDMFD sp!,
{r4-r11} ; dont need these now
- restore originals
copywords
ANDS r2, r2,
#7
; number of odd words to copy
BEQ
stop
; No words left to copy ?
wordcopy
LDR
r3, [r0], #4
; a word from the source
STR
r3, [r1], #4
; store a word to the destination
SUBS r2, r2,
#1
; decrement the counter
BNE
wordcopy
; ... copy more
stop
MOV
r0,
#0x18
; angel_SWIreason_ReportException
LDR
r1, =0x20026
; ADP_Stopped_ApplicationExit
SWI
0x123456
; ARM semihosting SWI
下面的这个程序实现同样的功能,每次只能传一个字:
AREA BlockData, DATA, READWRITE
src
DCD
1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst
DCD
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
END
AREA Word, CODE,
READONLY
; name this block of code
num
EQU
20
; Set number of words to be copied
ENTRY
; mark the first instruction to call
start
LDR
r0,
=src
; r0 = pointer to source block
LDR
r1,
=dst
; r1 = pointer to destination block
MOV
r2,
#num
; r2 = number of words to copy
wordcopy
LDR
r3, [r0], #4
; a word from the source
STR
r3, [r1], #4
; store a word to the destination
SUBS r2, r2,
#1
; decrement the counter
BNE
wordcopy
; ... copy more
stop
MOV
r0,
#0x18
; angel_SWIreason_ReportException
LDR
r1, =0x20026
; ADP_Stopped_ApplicationExit
SWI
0x123456
; ARM semihosting SWI
AREA BlockData, DATA, READWRITE
src
DCD
1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst
DCD
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
END
当处理器工作在ARM状态时,几乎所有的指令均根据CPSR中条件码的状态和指令的条件域有条件的执行。当指令的执行条件满足时,指令被执行,否则指令被忽略。
每一条ARM指令包含4位的条件码,位于指令的最高4位[31:28]。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面和指令同时使用。例如,跳转指令B可以加上后缀EQ变为BEQ表示“相等则跳转”,即当CPSR中的Z标志置位时发生跳转。
1、 B指令
B指令的格式为:
B{条件} 目标地址
B指令是最简单的跳转指令。一旦遇到一个 B 指令,ARM
处理器将立即跳转到给定的目标地址,从那里继续执行。注意存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是
24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26
位(前后32MB的地址空间)。以下指令:
B Label ;程序无条件跳转到标号Label处执行
CMP R1,#0
;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行
BEQ Label
3.3.6 批量数据加载/存储指令
ARM微处理器所支持批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操作。常用的加载存储指令如下:
— LDM 批量数据加载指令
— STM 批量数据存储指令
LDM(或STM)指令
LDM(或STM)指令的格式为:
LDM(或STM){条件}{类型} 基址寄存器{!},寄存器列表{∧}
LDM(或STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈或出栈。其中,{类型}为以下几种情况:
IA 每次传送后地址加1;
IB 每次传送前地址加1;
DA 每次传送后地址减1;
DB 每次传送前地址减1;
FD 满递减堆栈;
ED 空递减堆栈;
FA 满递增堆栈;
EA 空递增堆栈;
{!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。
基址寄存器不允许为R15,寄存器列表可以为R0~R15的任意组合。
{∧}为可选后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀时表示:除了正常的数据传送之外,还将SPSR复制到CPSR。同时,该后缀还表示传入或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。
指令示例:
STMFD R13!,{R0,R4-R12,LR}
;将寄存器列表中的寄存器(R0,R4到R12,LR)存入堆栈。
LDMFD R13!,{R0,R4-R12,PC}
;将堆栈内容恢复到寄存器(R0,R4到R12,LR)。
加载中,请稍候......