对部分需要加以注意或者不知道干嘛用的Cortex-M0/M0+指令给予个人理解层面的解释。完整的指令集请参考《Cortex-M0/M0+指令集》
mingdu.zheng at gmail dot com
http://blog.csdn.net/zoomdy/article/details/79308903
绝大部分指令只能访问low registers,也就是只能访问R0~R7寄存器。可以访问high registers的指令只有两条,这两条指令都不更新APSR,指令没有S后缀。
MOV <Rd>, <Rm> // Rm and Rn can be high or low registers.
ADD <Rd>, <Rm> // Rd = Rd + Rm. Rd, Rm can be high or low registers.
其它两条和SP加法有关的可以访问high registers的指令其本质是ADD指令。
ADD SP, <Rm> // 相当于 Rd 为 SP 的 ADD ,
ADD <Rd>, SP, <Rd> // 相当于 Rm 为 SP 的 ADD ,
函数内的临时变量分配到堆栈,进入函数给临时变量分配空间时使用SUB指令。
SUB SP, SP, #immed7 // SP = SP – ZeroExtend(#immed7<<2)
退出函数释放临时变量空间时使用ADD指令。
ADD SP, SP, #immed7 // SP = SP + ZeroExtend(#immed7<<2)
上面两条指令的立即数只有7位,最多可以增减SP指针127个字空间,如果超过127个字,使用这条指令:
ADD SP, <Rm> // SP = SP + Rm. Rm can be high or low register.
只有ADD指令,没有SUB指令,如果需要SUB,那么给Rm赋值负数即可。
在堆栈分配了临时变量空间后,总要取得临时变量的地址才能做进一步的操作。
ADD <Rd>, SP, #immed8 // Rd = SP + ZeroExtend(#immed8<<2)
立即数不够,可以用寄存器。
ADD <Rd>, SP, <Rd> // Rd = Rd + SP. Rd can be high or low register.
RSBS <Rd>, <Rn>, #0 // Rd = 0 – Rm, Reverse Subtract (negative)
这是倒过来的减法,常量减去寄存器值,而且常量只能是0。所以这条指令实质上就是一条取负数指令。
Rd = 0 - Rm
等价于:Rd = -Rm
Rd 寄存器值等于负的 Rm 寄存器值。
多寄存器加载指令
LDMIA <Rn>!, {<Ra>, <Rb>,..} // Load Multiple Increment After
用C语言来解释
p = Rn;
Ra = *p++;
Rb = *p++;
...
Rn = p;
多寄存器存储指令
STMIA <Rn>!, {<Ra>, <Rb>,..} // Store Multiple Increment After
用C语言来解释
p = Rn;
*p++ = Rn;
*p++ = Rb;
...
Rn = p;
LDMIA/STMIA用来优化大量数据访问的情况,Increment After 地址递增方式符合C语言的操作习惯,即从低地址开始,访问过后累加地址。