メディア
連載
» 2016年09月27日 11時30分 公開

スタックの役割Q&Aで学ぶマイコン講座(30)(2/3 ページ)

[菅井賢(STマイクロエレクトロニクス),EDN Japan]

スタックの基本動作

 マイコンのメインルーティン実行中に、例外処理(割り込み、フォールトなど)や関数実行によるサブルーティンが発生すると、マイコンはメインルーティンを中断し、演算途中のレジスターの値や実行していたプログラムカウンタ(以下、PC)など、復帰に必要な情報を一時的に保管します。その保管先を「スタック」と呼びます。スタックは高速アクセス可能なメモリを使う必要がありますので、通常は内蔵RAMが使われます。そして保管先を示すレジスターを「スタックポインター(以下、SP)」と呼びます。通常、SPは保管先の内蔵RAMのアドレスの値が入ります。

 メインルーティンへの復帰に必要な情報を「コンテキスト」と呼び、一時保管する動作を「PUSH(プッシュ/退避)」と呼びます。割り込み処理などが終わって、マイコンがメインルーティンに戻るとき、スタックの内容を元に戻します。この動作を「POP(ポップ/復帰、復元)」と呼びます。

 スタックは高速アクセスができる記憶装置であれば、特にRAMである必要はありませんので、マイコンによってはレジスター群をスタックとして使うものもあります。しかし、あまり一般的ではありませんので、この記事では、内蔵RAMをスタックとして使用する場合を想定します。

スタックポインター(SP)

 そもそもスタック(Stack)とは積み重ねるという意味です。従って、マイコンで言うスタックとはコンテキストを次々と積み重ねて保存することになります。すなわち、コンテキストがスタックに保存されるときにはSPで示されたアドレスから順次積み重ねるイメージで保存されます。「積み重ねる」と述べましたが、実際のマイコンでは、SPは減算され、アドレスの少ない方向に保存される場合が多いです。

 SPは、汎用レジスターとは異なり、PCや状態レジスター(一般的にCCRと呼ばれる)などの特殊レジスターに分類されます。初期値は、ユーザーが設定します。設定方法はソフトウェアで行う場合と、ハードウェアで行う場合があります。どちらで設定するかは製品の仕様によって異なります。

 例として、図2にSTマイクロエレクトロニクスのSTM32F103(ARM Cortex-M3プロセッサ搭載)のSPの設定方法を示します。

図2:スタックポインターの設定方法(STM32F103の例)

 STM32F103はメインスタック(SP_main)とプロセススタック(SP_process)との間で切り替わるバンクレジスターの構成になっています。メインスタックはベクターテーブルで指定します。プロセススタックはソフトウェアで設定します。

スタックの管理方法

 スタックは内蔵RAMに設定されますので、無限ではありません。置く場所を間違えると、多重割り込みなどで、スタックと関係ない他のデータを壊すことにもつながります。そのため、ユーザーはスタックを管理しなくてはいけません。

 スタックは、統合開発環境で容易に管理できます。ここでは、IARシステムズ製のIAR Embedded Workbench for ARM(EWARM)を例にとって説明します。

 例えば、実際の内蔵RAMの容量から、使用可能な最大スタックサイズを超えるような状況を知りたい場合、EWARMには2つの方法があります。それは、ビルド時点で、見積もりを表示する機能とデバッグ時点で表示する機能です。

 前者は、プロジェクトオプションのリンカカテゴリー→アドバンストタブから「スタックの使用量解析を有効化」と同じくリストタブの「リンカマップファイルの表示」にチェックをつけてビルドをすることで、マップファイルから、想定スタック使用量を確認することができます(図3参照)。

図3:統合ツールのスタック管理(ビルド時に確認する方法)

 後者のデバッグ時点で表示するには、図4-aに示すようにツールタグ→オプションタグから、スタックを開けて、管理したい項目にチェックします。デフォルトだと、「スタックポインターが境界外のときにワーニング」にチェックが入っています。

図4:統合ツールのスタック管理(デバッグ時に確認する方法)

 デバッグ動作で、ブレークポイントなどで止まった際に、スタックが外れているとデバッグログにワーニングが表示されます。「グラフィックスタック……」にチェックを入れると、同じくデバッガーを止めた際に、範囲を超えたら、あるいは設定閾(しきい)値を超えたらワーニングが表示されます。

 また、スタックがオーバフローを起こす直前で止めたいときの手段として表示タグ→ブレークポイントを開き、新規ブレークポイント→データにてスタックの上限のアドレスを指定し、例えばサイズを32などにしておくと、その範囲にCPUがアクセスした時点でブレークすることができます。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSフィード

公式SNS

EDN 海外ネットワーク

All material on this site Copyright © ITmedia, Inc. All Rights Reserved.
This site contains articles under license from AspenCore LLC.