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 );
}

 どうですか? 実際の処理に入る前に RememberA0( )、SetUpA4( ) を呼び出し、Xを抜ける前に RestoreA4( ) を呼び出すだけです。それを明確にするためにXの処理本体をサブルーチンに分けています。

 グローバル変数を使わないのであればこのような書き方をする必要はありませんが、これは習慣づけておいた方がいいでしょう。これから外部ウィンドウを作ったりダイアログでフィルタ処理をする時などはこの処理が必須になります。


Next



THINK C Lab.

UDI's HomePage
inserted by FC2 system