在日常编写Bug的时候,不知是否经过这样一种情况,我明明只是在函数中多加了一个临时变量,结果程序执行就异常了。我屮艸芔茻...
我碰到的一次情况是该函数程序访问数组本来就越界了,但是还能正常工作,就因为加了一个临时变量,栈内容发生了变化,就因为一个变量的偏移,在对数组操作时刚好设置给了LR寄存器,导致子程序返回有误,程序执行逻辑异常。
上述的这种问题,常规调试是无法发现的,甚至问题出现在那个地方都定位不到。
都说汇编代码时程序员的最后一根救命稻草。接下来就来介绍一下汇编中最常用的STM/LDM指令。
LDM翻译为Load Multiple registers
STM翻译为Store Multiple registers
LDM{addr_mode}{cond} Rn{!}, reglist{^}
STM{addr_mode}{cond} Rn{!}, reglist{^}
I为Increment(递增)
D为Decrement(递减)
B为Before
A为After
模式决定了基址寄存器是在执行指令前地址增减还是指令执行后增减。
D为Descending(降序)
A是Ascending(升序)单词首字母
F是单词Full 首字母,意思为当前的栈指针指向是最后一个入栈的元素
E是单词Empty单词首字母,意思是当前的栈指针指向的是下一个空闲空间
STMDB R13!,{R4-R6,R14}
逐步分析,STM为存贮指令,DB解释为当前栈地址是降序的且当前的栈指针指向栈中的最后一个元素。所以指令执行之前一定要让SP指向下一个空闲地址,执行完之后再将SP地址递减。
因为有!所以该指令执行完之后需要将最后的地址写回给Rn(即SP),所以最后SP的地址为0x3fffbf0
注意,因为栈地址是递减的,所以最先入栈的是R14,从右往左。如果栈是递增的则反之。
怎么样,你学废了吗?
END
→点关注,不迷路←
文章引用微信公众号"嵌入式微处理器",如有侵权,请联系管理员删除!