对Cortex-M0/M0+难理解指令的解释

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zoomdy/article/details/79308903

对部分需要加以注意或者不知道干嘛用的Cortex-M0/M0+指令给予个人理解层面的解释。完整的指令集请参考《Cortex-M0/M0+指令集》

mingdu.zheng at gmail dot com
http://blog.csdn.net/zoomdy/article/details/79308903

可访问high registers的指令

绝大部分指令只能访问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 <Rd>, <Rm>
ADD  <Rd>, SP, <Rd>  // 相当于 Rm 为 SP 的 ADD <Rd>, <Rm>

分配临时变量的指令

函数内的临时变量分配到堆栈,进入函数给临时变量分配空间时使用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指令

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语言的操作习惯,即从低地址开始,访问过后累加地址。

展开阅读全文

没有更多推荐了,返回首页