请解释一下以下不懂处:
1)原文:
周立功的《ARM微控制器基础与实战(第2版)》第7章7.3.6关于中断及时钟节拍中断,
程序清单7.10 IRQ异常处理代码的汇编语言部分
MACRO
$ IRQ_Label HANDLER $ IRQ_Exception_Function
EXPORT $ IRQ_Label (1)
IMPORT $ IRQ_Exception_Function (2)
$ IRQ_Label
SUB LR, LR, #4 ; 计算返回地址 (3)
STMFD SP!, {R0-R3, R12, LR} ; 保存任务环境 (4)
MRS R3, SPSR ; 保存状态 (5)
STMFD SP, {R3, SP, LR}^ ; 保存用户状态的R3,SP,LR,注意不能回写 (6)
LDR R2, = OSIntNesting ; OSIntNesting++ (7)
LDRB R1, [R2] (8)
ADD R1, R1, #1 (9)
STRB R1, [R2] (10)
SUB SP, SP, #4*3(11)
MSR CPSR_c, #(NoInt | SYS32Mode) ; 切换到系统模式 (12)
CMP R1, #1 (13)
LDREQ SP, =StackUsr (14)
BL $ IRQ_Exception_Function ; 调用c语言的中断处理程序 (15)
MSR CPSR_c, # (NoInt | SYS32Mode) ; 切换到系统模式 (16)
LDR R2, = OsEnterSum ; OsEnterSum,使OSIntExit退出时中断关闭 (17)
MOV R1, #1 (18)
STR R1, [R2] (19)
BL OSIntExit (20)
LDR R2, = OsEnterSum ; 因为中断服务程序要退出,所以OsEnterSum=0(21)
MOV R1, # 0 (22)
STR R1, [R2] (23)
MSR CPSR_c, # (NoInt | IRQ32Mode) ; 切换回irq模式 (24)
LDMFD SP, {R3, SP, LR}^ ; 恢复用户状态的R3,SP,LR,注意不能回写 (25)
LDR R0, = OSTCBHighRdy (26)
LDR R0, [R0] (27)
LDR R1, = OSTCBCur (28)
LDR R1, [R1] (29)
CMP R0, R1 (30)
ADD SP, SP, #4*3 (31)
MSR SPSR_cxsf, R3 (32)
LDMEQFD SP!, {R0-R3, R12, PC}^ ; 不进行任务切换 (33)
LDR PC, =OSIntCtxSw ; 进行任务切换 (34)
MEND
2)提问:
STMFD SP, {R3, SP, LR}^ ; 保存用户状态的R3,SP,LR,注意不能回写(6)
SUB SP, SP, #4*3 (11)
为何不直接用 STMFD SP!, {R3, SP, LR}^
LDMFD SP, {R3, SP, LR}^ ; 恢复用户状态的R3,SP,LR,注意不能回写(25)
ADD SP, SP, # 4*3 (31)
为何不直接用 LDMFD SP!, {R3, SP, LR}^
|
|