X作成講座 on TC(4) レジスタの待避と復帰
具体的にX作りに入る前に、少し基本形を変えましょう。
Xは「コードリソース」と呼ばれる特殊なプログラムです。通常の解説書で説明しているアプリケーションと違い、HyperCard の下で動作するモノなのでいくつか制約があることは述べました。もうひとつ、グローバル変数の問題があります。
ToolBox レベルのプログラムは全てCPUのレジスタ(CPU自身の持っている変数のようなもの:数は決まっている)をうまく使ってプログラムを動かします。通常A5というレジスタにはアプリのグローバル変数のアドレスが入っていることになっています。コンパイラでコンパイルしたプログラムはそれをアテにして動きます。
ところがハイパカというアプリから呼び出されるXというプログラムではこのA5というレジスタを使うわけにいきません。この値を書き換えたらハイパカが困ってしまいますからね。
そこでXではA5レジスタはそのまま温存し、A4レジスタを使ってグローバル変数にアクセスします。そのための THINK C 独特の作法が RememberA0( )、SetUpA4( )、RestoreA4( )の3つのコールです。CodeWarrior ではまた別の作法を使うので気を付けて下さい。
tasu.c のソースを、この作法に則った書き方に変えてみます。
#include "HyperXCmd.h" #include "SetUpA4.h" /* Prototypes */ void myRoutin( XCmdPtr paramPtr ); /* Main */ pascal void main( XCmdPtr paramPtr ){ RememberA0( ); SetUpA4( ); myRoutin( paramPtr ); RestoreA4( ); } /* my routin */ void myRoutin( XCmdPtr paramPtr ){ long n1, n2; Str255 theStr; ZeroToPas( paramPtr, *paramPtr->params[0] , theStr ); n1 = StrToNum( paramPtr, theStr ); ZeroToPas( paramPtr, *paramPtr->params[1] , theStr ); n2 = StrToNum( paramPtr, theStr ); NumToStr( paramPtr, n1 + n2, theStr ); paramPtr->returnValue = PasToZero( paramPtr, theStr ); }