[ad_1]
你好 !
我一直在学习易失性是如何工作的,因为我使用微控制器,我部分需要知道它是如何工作的。 我已经了解了伪汇编代码如何在网站上工作。 我将添加此信息以显示我所知道的以及我想要蚕食的内容。
因此, 易失性 阻止编译器优化他认为不会在大摘要中更新的变量或编译器优化的其他进程。
像这样的东西:
非挥发性:
move the value of variable m into internal register A label: if A != 1 goto done goto label done: carry on
所以变量 m
被读取一次并且永远不会读取该值 m
再次尽管 m
可以改变它的值。 它认为它永远不会改变
易挥发的 :
label:<br /> move the value of variable 'm' to internal register A<br /> if A != 1 then go to done<br /> go to label<br /> done:
这里使用 volatile 它将每次读取什么变量 m
有里面。
ISR(中断路由)看起来怎么样?
这是我从网站上读到的一个示例,它告诉我很多它是如何工作的。
引用:* 在主循环中 – 在执行 ISR 之前 – 它在寄存器 1 中具有值“X”
* ISR启动,ISR将register1(X)的值保存到SRAM(堆栈?)
* ISR 使用寄存器 1 及其自己的值,加载 abc,更改 def …任何内容,执行操作
* 在返回 main() 之前,它将值“X”恢复到寄存器 1 中。
变量值保存在内存/RAM等中,其中操作存储在寄存器中。 这让我很清楚,ISR 只更新内存中的变量值,而不是寄存器中的变量值,因为寄存器会返回到修改之前的先前状态。
凉爽的
现在我想知道的是 volatile 是如何工作的等,因为我部分知道它是如何工作的。 我想知道如何在调试器中看到它。
让我们用这个例子:
int A = 0; int main() { while(A != 1) { //Do something } } void ISR() { A++; }
这是一个没有易失性的简单代码。 想知道调试器的行为方式。
int A = 0; int main() { while(A != 1) { //Do something } } void ISR() { A++; <----- breakpoint }
我在这里设置了断点。
变量 A 从 0 更新为 1。但是 while 循环不会读取变量 A,而是经过优化,会从寄存器中读取值 0,就像我在开头所说的那样。
好的,变量 A 从 0 更新为 1,调试器将显示 A 的值是 1 而不是 0。
int A = 0; int main() { while(A != 1) <----- breakpoint { //Do something } } void ISR() { A++; }
因此,在 ISR 之后,调试器现在跳转到主程序并在 while 处停止,因为这是我的下一个断点。
A 的值是多少? 它仍然会像我一开始所说的那样是“1”吗? A 应该仍然是 1,而 while 应该让我通过,因为即使 A = 1 并且 while 循环说 A != 1 它仍然应该通过,因为 while 从寄存器而不是从变量 A 读取数据,因为它不是易失性的。
为什么我需要这些知识? 对于未来,如果我忘记了并且会发生一些奇怪的事情,这将帮助我知道我是否忘记了类似的事情。 为什么即使条件不匹配,while 循环也会启动。
相信你明白我在这里想说的是什么。
我尝试过的:
我不知道它会是什么样子,因为我的微控制器没有优化非易失性变量,就好像它们是易失性的一样,所以我在正常情况下寻求知识;D
解决方案1
我认为优化取决于编译器。 我非常熟悉 gcc 编译器和这里给出的代码;
int A = 0; int main() { while(A != 1) <----- breakpoint1 { //Do something } } void ISR() { A++; <----- breakpoint2 }
断点 2 处的值将为 0->1,断点 1 处的值您将得到“该值已优化”,因为该值位于寄存器中,一旦 PC 离开 ISR,该值就会消失。
volatile int A = 0; int main() { while(A != 1) <----- breakpoint1 { //Do something } } void ISR() { A++; <----- breakpoint2 }
当使用 volatile 关键字时,断点 2 处的值将为 n->n+1,断点 1 处的值将为 n,并且该值将显示在调试器中。
[ad_2]
コメント