四、内核实例
为了让读者有个更加深刻的理解, 以内核中的例子为例:
arch/arm/kernel/setup.c
void notrace cpu_init(void)
{
unsigned int cpu = smp_processor_id();----获取CPU ID
struct stack *stk = &stacks[cpu];----获取该CPU对于的irq abt和und的stack指针
……
#ifdef CONFIG_THUMB2_KERNEL
#define PLC "r"----Thumb-2下,msr指令不允许使用立即数,只能使用寄存器。
#else
#define PLC "I"
#endif __asm__ (
"msr cpsr_c, %1 "----让CPU进入IRQ mode
"add r14, %0, %2 "----r14寄存器保存stk->irq
"mov sp, r14 "----设定IRQ mode的stack为stk->irq
"msr cpsr_c, %3 "
"add r14, %0, %4 "
"mov sp, r14 "----设定abt mode的stack为stk->abt
"msr cpsr_c, %5 "
"add r14, %0, %6 "
"mov sp, r14 "----设定und mode的stack为stk->und
"msr cpsr_c, %7"---回到SVC mode
:----上面是code,下面的output部分是空的
: "r" (stk),----对应上面代码中的%0
PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),----对应上面代码中的%1
"I" (offsetof(struct stack, irq[0])),----对应上面代码中的%2
PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),----以此类推,下面不赘述
"I" (offsetof(struct stack, abt[0])),
PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
"I" (offsetof(struct stack, und[0])),
PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
: "r14");----上面是input操作数列表,r14是要clobbered register列表
}