1.6.1. macros stmia

/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */

@
@ IRQ stack frame.
@
#define S_FRAME_SIZE	72
1
#define S_OLD_R0	68
#define S_PSR		64
#define S_PC		60
#define S_LR		56
#define S_SP		52

#define S_IP		48
#define S_FP		44
#define S_R10		40
#define S_R9		36
#define S_R8		32
#define S_R7		28
#define S_R6		24
#define S_R5		20
#define S_R4		16
#define S_R3		12
#define S_R2		8
#define S_R1		4
#define S_R0		0

#define MODE_SVC 0x13
#define I_BIT	 0x80

/*
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 */
	.macro2	bad_save_user_regs

	sub	sp, sp, #S_FRAME_SIZE3
	stmia4	sp, {r0 - r12}			@ Calling r0-r12
	ldr	r2, _armboot_start  5  
        

1

此处很简单,只是一些宏定义而已。

后面用到的时候再解释。

2

.macro和后面的.endm相对应,其语法是:

图 1.12. macro的语法

macro的语法


所以,此处就相当于一个无参数的宏bad_save_user_regs,也就相当于一个函数了。

3

sp

= sp- S_FRAME_SIZE

= sp - 72

4

stmia的语法为:

图 1.13. LDM/STM的语法

LDM/STM的语法


其中,条件域的具体含义如下:

图 1.14. 条件码的含义

条件码的含义


更具体的含义:

六、批量数据加载/存储指令ARM微处理器所支持批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操作。常用的加载存储指令如下:

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)。

所以,此行的含义是,

将r0到r12的值,一个个地传送到对应的地址上,基地址是sp的值,传完一个,sp的值加4,一直到传送完为止。

此处,可见,前面那行代码:

sp = sp - 72

就是为此处传送r0到r12,共13个寄存器,地址空间需要13*4=72个字节,

即前面sp减去72,就是为了腾出空间,留此处将r0到r12的值,放到对应的位置的。

5

此处的含义就是,将_armboot_start中的值,参考前面内容,即为_start,

而_start的值:

从 Nor Flash启动时:_stat=0

relocate代码之后为:_start=TEXT_BASE=0x33D00000

此处是已经relocate代码了,所以应该理解为后者,即_start=0x33D00000

所以:

r2=0x33D00000