找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1699|回复: 2
收起左侧

关于Cortex-M4内核的一个小问题

[复制链接]
回帖奖励 6 黑币 回复本帖可获得 1 黑币奖励! 每人限 1 次
ID:474802 发表于 2021-2-26 11:24 | 显示全部楼层 |阅读模式
本帖最后由 MNwcy 于 2021-2-27 11:13 编辑

在看Cortex-M4的资料,就是权威指南那本书的时候,看到了关于异常发生时的入栈叙述, 123.png 444.png 666.png 看到这里有点疑问了,我的疑问就是“为什么入栈保存的只有八个字的数据?”对于这个不懂的地方我有几点思考,希望前辈们能不吝解惑。
1.我在看资料时还知道了,寄存器R0~R3、R12、LR、PSR的八个字大小的值会在异常发生后进行入栈操作,这几个寄存器被叫做“调用者保存寄存器”,R4~R11寄存器被叫做“被调用者保存寄存器”,也就是说,调用者保存寄存器是异常中断发生时 ”父函数“需要入栈保存的部分,而“被调用者保存寄存器”在进入到“子函数”中需要由子函数进行暂存,然后在子函数结束返回父函数时进行 被调用者寄存器 恢复。关于这两个概念我不了解,这个规范的好处是什么。网上的论坛搜到的问答感觉模棱两可,如果有人懂的话欢迎解答。2.在查资料的过程中,看到有人说的是栈帧“八个字”大小,只是“官方标配”,根据实际的情况,编译器会将需要存储的量都入栈,也就是说栈帧的大小并不是固定的。但是从权威指南那本书中看,栈帧大小不是八字就是26字(包含了浮点数寄存器)。这里是相互冲突的。
3.我的一点猜测,是不是在函数A执行过程中只要其未完全执行完毕(比如被异常B中断或调用子函数C),函数A在RAM中所占动态内存是不是就不会释放。这样也就解释了为什么只有内部通用寄存器的数值需要入栈保存,当从中断B或者函数C返回时,恢复通用寄存器内的值,然后从返回地址处继续执行即可。

回复

使用道具 举报

ID:474802 发表于 2021-2-28 19:24 | 显示全部楼层

欢迎讨论
回复

使用道具 举报

ID:474802 发表于 2021-3-7 23:39 | 显示全部楼层
自己挖的坑自己填!经过一番小研究有所收获,总结一下:
1.关于子函数调用和异常中断处理是两种不同的情况,子函数调用是一个明确的关系,比如说我程序执行到哪里会调用这个子函数都是已知的(编译期间就能确定的)。而异常和中断的出现位置是不可知的。
2.举个例子在A函数中调用了B函数,各个函数怎么执行的在编译期间就确定了,当A调用B时,此时内部寄存器中的数据在执行完B后A还要接着用,所以就把调用B时会被改变的寄存器入栈保存(当然还有LR寄存器,入栈后LR会自动更新)
3.中断和异常想来就来,所以并不确定是在那个位置跳转到异常处理部分的,所以当异常中断来后就会把所有的内部寄存器保存(这就是所谓的栈帧,所以栈帧的大小也是固定的,注意入栈是区分调用者寄存器和被调用者寄存器,入的栈不同)
进调试看下汇编就明白了。有说的不对的欢迎指正

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表