【解決方法】揮発性 – デバッガーには何が表示されますか?


こんにちは !

私はマイクロコントローラーを使用しているため、volatile がどのように機能するかを学んでいます。その仕組みを知るには部分的に必要です。 疑似アセンブラー コードに関して、Web サイトがどのように機能するかを学びました。 私が知っていることと、少し知りたかったことを示すために、この情報を追加します。

したがって、volatile は、大きな概要で更新されないと思われる変数を最適化するためにコンパイラーを停止したり、他のプロセスがコンパイラーによって最適化されないようにしたりします。

このようなもの :

不揮発性:

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 (割り込みルート) ではどのようになりますか?
これは私が Web サイトから読んだ例で、どのように機能するかについて多くのことを教えてくれます。

引用:

* メインループ内 – ISR が実行される直前 – register1 に値「X」があります
* ISR が開始され、ISR は register1 (X) の値を SRAM (スタック?) に保存します。
* ISR はレジスタ 1 を独自の値で使用し、abc でロードし、def に変更します…何かを実行し、操作を実行します
* main() に戻る前に、値「X」を register1 に復元します。

変数の値はメモリ/RAM などに保存され、演算はレジスタに保存されます。 これにより、レジスタは変更前の状態に戻るため、ISR はレジスタではなくメモリ内の変数値のみを更新することが明確になりました。

いいね

さて、私が知りたかったのは、揮発性がどのように機能するかなどです。なぜなら、私はそれがどのように機能するかを部分的に知っているからです。 デバッガーでどのように表示されるのか知りたいです。

この例を使用してみましょう:

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 を読み取ります。

OK、変数 A が 0 から 1 に更新されたので、デバッガには A の値が 0 ではなく 1 と表示されます。

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 からではなくレジスタからデータを読み取るため、通過するはずです。これは、変数 A は揮発性ではないためです。

なぜこの知識が必要なのでしょうか? 将来、忘れて何か奇妙なことが起こった場合に備えて、これは次のようなことを忘れたかどうかを知るのに役立ちます。 条件が一致していないにもかかわらず、while ループが開始されるのはなぜですか。

ここで私が言おうとしていることは理解していただけると信じています。

私が試したこと:

私のマイクロコントローラーは非揮発性変数を揮発性変数であるかのように最適化しなかったため、それがどのように見えるかわかりませんでした。そのため、通常は見ずにむしろ知識を求めています ;D

解決策 1

最適化はコンパイラに依存すると思います。 私は gcc コンパイラーとここに示されているコードに精通しています。

C++
int A = 0;

int main()
{
	while(A != 1) <----- breakpoint1
	{
	//Do something
	}
}

void ISR()

{
	A++; <----- breakpoint2
}

ブレークポイント 2 の値は 0->1 になり、ブレークポイント 1 の値はレジスタ内にあり、PC が ISR を離れると値が失われるため、「値は最適化されました」というメッセージが表示されます。

C++
volatile int A = 0;

int main()
{
	while(A != 1) <----- breakpoint1
	{
	//Do something
	}
}

void ISR()

{
	A++; <----- breakpoint2
}

volatile キーワードを使用すると、ブレークポイント 2 の値は n->n+1 になり、ブレークポイント 1 の値は n になり、その値がデバッガーに表示されます。

コメント

タイトルとURLをコピーしました