NaoPPIC18Fでは(PIC12やPIC16など比べ)プログラムによるスタック操作が追加されています。サブルーチン呼び出しの際にPCがスタックにPUSHされ、ReturnでPOPされます。これまでPICではプログラムから利用できるスタックがありませんでした。PIC18FではニーモニックにPUSHとPOPが加わりました。他のCPUと比べ、スタックの使い方には注意が必要です。スタックメモリは、プログラムメモリ空間やFAST(ワーク)メモリ空間から分離されており、内容を直接自由にアクセスはできません。リセット後は、スタックポインタは0(最先位置ポインタ)ですが、ここにはスタックメモリがありません。PUSHを実行するとスタックポインタが+1され、次にPC+2がスタックに追加されます。これは、PUSHは1ワード(2バイト)命令なので、戻りの際のアドレスがスタックされます。PUSHの場合、スタックに入る値はPOPで捨てられますので、スタックをReturnに使用するテクニック以外ではあまり意味を成しません。スタックメモリは別空間にあるため、TOSレジスタ(PC幅と同じく21bit)を通して現在のスタックポインタ位置の1レベルのみを部分の的にアクセスできます。Push命令の実行直後は、結果として、呼出Push命令のプログラムアドレスに+2(PC+2)した21bitアドレス値がTOSレジスタに現れます。POP命令でスタックポインタは-1されます。POPにより、TOSレジスタが指す内容がPUSH前の状態に戻ります。理解しやすいように、マニュアルの補足をします。TOSレジスタは、スタックポインタと連動した、スタックメモリの読み書きウィンドです。スタックポインタの指す位置は、一般的なCPUのように次に使用する空間を指しているのではなく、呼び出したルーチンへの戻りアドレスがそのまま見えているので、この内容を変更するとルーチンから戻れなくなります。pushを実行することで、スタックレベルが1つ上がり、TOSが指し示す値は、現在使用していないスタックメモリへの位置(内容)となります。マニュアルを見ても特には書かれていませんが、CPUを設計された方の意図としては、たぶんPUSH・POP命令と、TOSを用いた21ビット(TOSL8bit、TOSH8bit、TOSU5bit)の退避型ワークの提供を目的としていると考えます。サブルーチン等で最初にpushを実行し、最後にpopすることで、その間ではTOS(21bit)が外部ルーチンから保護された独立したワークとして利用できます。←スタックは31レベルもあります。割り込みやサブルーチンのワークとして、容量は限られますが利用できます。多重での割り込み、サブルーチンでは必須であり、WSやステータス、FSR,BSRなど重要なレジスタの保存、ループカウンタなどいろいろ応用ができます。マクロでの利用例を示します。←文中にTabが入れられないので、くっついています。注意:インストラクションとしてmovffでは、TOSをdistinationとして転送できない。逆方向の転送は可WREGとSTATUSを保存します。ステータスレジスタは、MOVFF命令により最後に戻す。割り込みなどで重要です。BSRpopendmFSRnの保存マクロ引数は値として処理されるが、マクロ中の#v(para)記述は、para部分がマクロ呼び出しのTrimされた文字列に置換される。TOSレジスタの実体はスタックメモリなので、データビット幅はPC(ProgramCounter)と同じ21bit幅です。PIC18Fで一度にアクセスできるデータ(レジスタ)幅は8ビットです。(もしくは1ビット)TOSL,TOSHレジスタは8bitとして利用できますが、最上位TOSUレジスタは5bitしかありません。TOSUの読み出すと上位3ビットは常に0となります。[追記-2017-07-26]サブルーチンを呼び出す際、TOSにパラメータを入れて渡すことはできません。Call命令実行により、スタックがPushされるため、当然TOSレジスタが指す先が移動します。TOSから取り出すと、戻りPCを挿しており引き渡し値ではありません。スタック内に保存されたデータのアクセスについて、割り込みをとめてStackPointerを直接操作すれば、できなくはありませんが、PIC18はSP間接アドレッシングはできませんので、高級CPUのようにはうまくいきませんね。Modeで動作させてワークを使ったほうがスマートですね。WordPress.。