ファンクション - みる会図書館


検索対象: 月刊 C MAGAZINE 1991年7月号
26件見つかりました。

1. 月刊 C MAGAZINE 1991年7月号

TabIe 1 プログラムのロードと実行 DOS ファンクション 4B00h プログラムのロードと実行 引数 返り値 機能 AH : 4Bh AL ニ 00h なし INT 2 1 h ES:BX : ノヾラメータブロックの位置 DS:DX : 起動するノヾス名の位置 ES: BX にロードするためのバラメータブロックの位置を指定する。 DS: DX に起動するバス名の ASC 日文字列の位置を指定し , ノヾラメータブロックの内容は以下のとおり。 オフセットバイト数内容 00h 02h 06h OAh 4 4 2 4 渡される環境のセグメントアドレス 00h の場合 , 親環境をコピーする。 PSP のオフセット 80h のコマンドラインに対するポインタ コマンドラインの形式は以下のとおり コマンドライン文字列 ↑ CR を除く文字数 ( 1 バイト ) CR PSP6Ch に渡すテフォルト FCB に対するポインタ PSP5Ch に渡すテフォルト FCB に対するポインタ 新 MS - DOS プロクラミンク入門 C プログラマのための ますが , func tst. c によるサイズの比較を イラの system() 関数とは仕様が一部異なり ようにコンパクトに記述て、きます。コンパ tem( ) 関数は system. c ( 付録ディスク収録 ) の , spawn. c の関数を使用すると sys 用するほうが賢いて、しよう ) 。 わなくなります ( ならばライプラリ関数を使 と , サイズがライプラリ関数とそれほど違 す。しかし , このように仕様を膨らませる などのバージョンアップ項目があげられま する が , 指定した環境変数も渡せるように 数をそのまま子プロセスに渡している ② spawn. c, spawnp. c では現在の環境変 . COM, . EXE の順に検索する ①コマンド名の拡張子を省略した場合 , くればかなり実用的な関数て、すが , さらに TabIe 2 子プロセスからのリターンコードの取得 DOS ファンクション 4Dh 子プロセスからのリターンコードの取得 引数 返り値 機能 AH ニ 4Dh INT 21 h AX : リターンコード DOS ファンクション 31h または 4Ch て指定するリターンコードを 1 回だけ AL レジスタに返す。 AH : 3 常駐終了 ( DOS ファンクション 31h による終了 ) AH : 2 八一ドエラー AH : 1 く CTRL 十 C > による終了 AH ニ 0 通常終了 ( DOS ファンクション 4Ch による終了 ) AH レジスタはプログラムの終了状態で次のとおりである。 TabIe 3 ファイルの検索 searchenv 関数 (MS-C) #include く stdlib. h> VOid searchenv( name, env var, path char * name Cha 「 * env var char * path 検索するファイル名 検索するティレクトリを示す環境変数 フルノヾス名を格納するバッファ name て指定されたファイルを ①カレントティレクトリ ② env va 「で指定されたティレクトリ の順て検索する。 ファイルが見つかると path にフルバス名を格納し , 見つからないと path の先頭に ' \ 0 ' をセットする。 searchpath 関数 (Turbo C 2.0 灯 u 「 bo C 十十 1 .0 ) #include く dir. h> char * searchpath ( file char * file 検索するファイル名 f ⅱ e で指定されたファイルを ①カレントティレクトリ ② PATH て指定されたティレクトリ の順で検索する。 ファイルが見つかるとフルノヾス名の文字列へのポインタを返し , 見つからないと NULL を返す。 Table 4 に示します。 Turbo C / C 十十て、は それほど差はありませんが , MS ー C て、は 2.5 K バイト弱の差が生じています。プログラム をコンパクトにしたい場合には有効て、しょ う ( 筆者は spawn. c, spawnp. c, system. c に 相当するプログラムをアセンプラて、記述し て自作ライプラリに登録しています ) 。 system. c て、使用している DOS ファンクシ ョン 37h(TabIe 5 ) は非公開のファンクショ ンて、 DOS のスイッチキャラクタの取得と変 更を行うものて、す。スイッチキャラクタと いうのは , COMMAND /C BATNAM におけるソ〃のことてす。 DOS ファンクショ ン 37h を使用すれば switchar. c ( 付録ディスク 収録 ) のような簡単なプログラムてスイッチ キャラクタをヾノなどに変更することも可能 て、す。しかし , コンパイラの system() 関数 が , スイッチキャラクタをソ〃と固定してい るものも少なくないため , スイッチキャラ クタを変更すると誤動作するプログラムも 少なくありません。たとえば , スイッチキ ャラクタをヾー〃に変更すると MS-C 5.1 / 6.0 ては func tst. c は誤動作します (Turbo C/ C 十 + ては正常に動作します ) 。実は筆者が 新 MS - DOS プログラミング入門 77

2. 月刊 C MAGAZINE 1991年7月号

ライフホ - ト lnformation from Compiler Makers 田 ov bp, offset DGROUP :-rdata Lattice C Q ー f オプションを使って 8087 命 令をインライン展開していますが , 8087 を搭載していないマシンで使 用するとハングアップしてしまい ます。これを避ける方法はありま せんか ? A LatticeC て、はスタートアップ ルーチンの中て、 , 80X87 の有無をチ ェックして外部変数 NDP に格納 しています。 80X87 があれば NDP 1 となり , 80X87 がなければ NDP = 0 となります。例として , プログラムの冒頭て、 List 1 のように し , 80X87 がなければ実行を中止し てください。 Q DOS 工クステンダ「 DOS / 16M 」 を使用していますが , 引 OS ルーチ ンを使用する場合は , どうすれば よいでしようか ? A DOS / 16M 上てのプログラム は , プロテクトモード状態て実行 するのて , リアルモード用に書か れた BIOS ルーチンを使う場合に は , ちょっとした工夫が必要てす。 この工夫は BIOS のパラメータ に , ポインタが含まれているかど うかて変わります。なお , DOS の ファンクションコールならば , Table 1 にあげたもの以外は自動 的にシミュレートしますから , プ ログラムを手直しする必要はあり ません。 印 OS のパラメータにポインタが含 まれていない場合 PC ー 9801 のディスク BIOS のシー クファンクションのように , BIOS を呼び出すときのレジスタ設定が 値のみの場合には , リアルモード プログラムと同じように扱えます。 DOS / 16M て、は割り込みが発生す ると , プロテクトモードからリア ルモードに切り換えることをデフ オルトとしているからてす。 List 2 のプログラムは , リアルモードの プログラムても DOS / 16M のプログ ラムて、も動作可能てす。 引 OS の / ヾラメータにポインタが含 まれている場合 PC ー 9801 のディスク BIOS のデー タの読み出しファンクションのよ うに , BIOS を呼び出すときのレジ スタ設定にポインタ ( アドレス ) が 含まれている場合には , そのポイ ンタをリアルモードのポインタに 変換する必要があります。 プロテクトモードては , アドレ スはすべて論理アドレスとなって おり , セグメントアドレスはディ スクリプタテープルへのインデッ クスとなっています。この論理ア ドレスをそのままリアルモードて 動作する BIOS に渡すと , BIOS は プログラムの意図とはまったく異 なるアドレスに書き込みます。 また BIOS がアクセスてきるアド レスは , IM バイト以下のアドレス て、あるため , BIOS に渡すアドレス のエリアは IM バイト以下のメモリ に確保しなければなりません。ま とめると以下のようになります。 ① IM バイト以下のメモリを確保 する ②①て確保したメモリのアドレス をリアルモードのアドレスに変 換する ③②のアドレスをレジスタに設定 して BIOS を呼び出す これを簡単に実現するためのプ TabIe 1 手直しが必要な DOS ファンクションコール ファンクションサプファンクション 4Bh 26h 44h 65h 01 H 以上 12 / 13 Load overlay など Create PSP gene 「 ic IOCTL functions Get Extended Country lnformation の monocase routine FCB を使うレ 0 ファンクションは , DTA の大きさとしてテフォルトの 128 バイトのみのサポート List 1 extern unsigned char -NDP; mai ・ n() if( ! -NDP ) { printf( ”韓* 数値演算プロセッサ 80X87 がありません。 yn"); List 2 exit(l): 凱 OV 第 OV 第 OV int ah, 10h al,90h c し 4 1 bh シークファンクション : デバイス種別ュニット番号 (DA/UA) : シリンダ番号 (C) : ディスク田 OS の呼び出し List 3 mov ah, MU し TRK + DB し DENS + REQSEEK + READFUNC ends _DATA -rdata db DTL dup(?) : データバッファ rdata public _DATA segnnet word public ・ DATA DGROUP group DATÅ : ディスク田 OS 呼び出し データバッフアのセグメントアドレス データバッフアのオフセットアドレス : セクター長 (N) : セクター番号 (R) : ヘッド番号 (H) : シリンダ番号 (C) : データ長 : デパイス種別ユニット番号 (DA/UA) データ読み出しファンクション int lbh 田 ov es. DGROUP 第 ov ch, SEC し EN 田 ov dl, SBCNUH 田 ov dh, HEDNUM mov cl, CY し NUM 田 ov bx, DTL nov al. DAUAO ロテクトモード変換ユーティリテ ィ MAKEPM に -TD オプションを 指定すると ,DGROUP がトランス ペアレントな状態になります。ト ランスペアレントとは , 論理アド レスと , それに対応する物理アド レスが同じ値てあるアドレスのこ とてす。したがって , アドレスを 渡す BIOS を呼び出すプログラムの 場合 , MAKEPM の -TD オプショ ンを指定してください。これて List 3 のようなプログラムも実行てきま す。 lnformation from Compiler Makers 161

3. 月刊 C MAGAZINE 1991年7月号

C プログラマのための マシンて、あれば動作するはずて、す。 7 常駐型 EXP 起動ユーティリティ 前述のユーティリティは , 起動にあたっ て , EXP ファイルを意識する必要がありま す 0COM, EXE, EXP ファイルを常に意識 してコマンドを使用するのは辛い面があり ます ODOS ューザて.COM ファイルと EXE フ アイルの違いを意識して起動している人は ほとんどいないて、しようから , て、きれば EXP ファイルも EXE, COM ファイルと同じよう な感じて、起動したいものて、す。そのために は KI-ShelI などの DOS シェルて、処理するの がもっとも望ましいのて、すが , 筆者は公表 て、きるような DOS シェルを作成していない ため , DOS ファンクションに割り込む簡単 なユーティリティを作成してみました。 入力文字列 CR EXE , COM ファイルに加えて , EXP ファ 実際に入力された CR を除く文字数 ( 1 バイト ) イルも起動て、きるようにするための方法は ( 本ファンクションが設定する ) いくつか考えられます。たとえば , CR を含むバッフア内の最大文字数 ( 1 バイト ) ( ユーサが設定する ) ① EXP ファイルを EXE ファイルにリネー ムして DOS ファンクション 4B00h ( Tab TabIe 7 PSP アドレスの取得 1 ) に割り込んで , ファイルヘッダで判 DOS ファンクション 62h PSP アドレスの取得 断する 引数 AH : 62h INT 21 h ② DOS ファンクション 0Ah(TabIe 6 ) に割 返り値 BX : PSP セグメントアドレス り込んで , 起動ファイルが EXP ファイ 機能実行中のプロセスの PSP セグメントアドレスを BX レジスタに返す。 ルの場合は DOS ー Extende 「経由で起動 非公開の DOS ファンクション 51h と同し機能である。 くのに時間がかかり , アクセス速度の遅い 説明は省略します。詳細は exp. c を参照して などの方法が考えられます。 ードディスクて、はけっこう待たされるこ ください ①の方法は EXE ファイルヘッダの先頭が とがあります ( EXP ファイルは当然 PATH の コンパイルは以下のようにして行ってく MS ー DOS の場合は、、 MZ クて、あり , EXP ファ 終わりのほうにパスを設定するて、しようか ださい イルの場合はヾ MP 〃 , や P2 〃 , P3 ' ′てあるた ・ MS-C 5 . 1 / 6 . 0 め , 拡張子を EXE に変更しても , 判別可能 また , DOS-Extender は RUN386. EXE, cl /J /W3 /Zp exp. c /link て、す。 EXP ファイルの場合は引数を設定し EXE386. EXE て、あれば PATH のリストを検 / st : 0X2800 / cp : 0X500 直して , DOS-Extender 経由て、起動すればよ 索して自動的に起動します。 RUN386, いわけて、す。ただし , DOS-Extender が拡張 EXE386 以外の場合は環境変数 RUN386 て、 子を EXP と仮定しているため , 起動の前後 tCC ¯W exp. C 指定してください 本ユーティリティは PC ー 9801 シリーズの MS て、リネームするなどの対策を取る必要があ ー DOS 3.3B と FM ー TOWNS の MS ー DOS ります。また , 拡張子を EXE にするとユー コンヾイル 3.1 て、動作を確認しています。機種依存する ティリティが常駐していないときは誤動作 簡単なプログラムなのて、 , プログラムの 部分はないため , MS ー DOS 3. x が動作する する危険性があります。 Fig. 3 コマンドの前に DOS ー Extende 「を指定する 80 10 extcmd argl arg2 CR ↓ 80 1 E 「 un386 a:*dir*extcmd a 「 gl arg2 CR 実際に入力された CR を除く文字数 CR を含むバッフア内の最大文字数 ↑ TabIe 6 バッファつきキーホード入力 DOS ファンクション OAh 八ッファつきキーホード入力 引数 AH ニ OAh DS:DX = 入力ノヾッフアへのポインタ ー NT 2 1 h 返り値 なし 機能 以下のフォーマットて入力文字列をセットする。 このファンクションは入力中に DOS のテンプレート機能が使用できる。 DS: DX ↓ ・ Turbo C/C 十十 新 MS-DOS プログラミング入門 79

4. 月刊 C MAGAZINE 1991年7月号

TabIe 17 プリンタのステータス取得 引数 返り値 機能 プリンタ引 OS ファンクション 12h AH = 1 2 h INT 1 Ah AH = ステータス情報 ピット 0 = 1 : テータ出力可能 ピット 0 = 0 . テータ出力不可能 ステータス取得 ( PC ー 9801 ) プリンタのステータス情報を取得する 00 Q プログラミング研究 exe2bin escptc escptc.com スタックチェックを行うスイッチ -N を指定 て、あることがよくわかると思います。なお , のタイニィモデルのコンパイル手順と同じ イスドライバて、あるにもかかわらず , 普通 が , 無視してください。これを見ればデバ コンパイル <Warning がいくつか出ます del escptc. exe TabIe 18 IOCTL キャラクタテパイスからの制御テータ受信 引 DOS ファンクション 4402h IOCTL キャラクタテノヾイスからの制御テータ受信 AH=44h AL=02h BX = 八ンドル 数 返り値 CX = 制御テータのバイト数 DS : DX = 制御テータバッフアのアドレス INT 21 h キャリー AX = 01 h : 無効なファンクション AX=06h : 無効な八ンドル キャリー = 0 AX : 転送されたバイト数 IOC.TL 制御テータをキャラクタテパイスから受け取る テノヾイスドライバが IOCTL I/F をサポートしている必要がある 機能 TabIe 19 オフセット 十 00h 十 01 h 十 1 Oh 十 1 1 h TabIe 20 オフセット 十 00h 十 01 h TabIe 21 テータの並び ノヾイト数 1 1 内 漢字モード指定コマンド出力バイト数 漢字モード指定コマンド出力テータ ANK モード指定コマンド出力バイト数 ANK モード指定コマンド出力テータ リクエストヘッダの転送バイト数が 32 ノヾイト以外の場合 バイト数 31 1 内 コマンド出力バイト数 コマンド出力テータ 引 数 返り値 機能 IOCTL キャラクタテパイスへの制御テータの送信 DOS ファンクション 4403h IOCTL キャラクタテパイスへの制御テータ送信 AH=44h AL=03h BX = 八ンドル CX = 制御テータのバイト数 DS : DX = 制御テータバッフアのアドレス INT 21 h キャリー AX = 01 h : 無効なファンクション AX=06h 無効なハンドル キャリー = 0 AX . 転送されたバイト数 IOCTL 制御テータをキャラクタテノヾイスに送る テパイスドライバが IOCTL I/F をサポートしている必要がある してはいけません。 MS-C MS ー C て、は次のようにコンパイルしてくだ cl /AT /J /Gs /W3 /zp escptc. c コンパイルて、 Warning がいくつか出ます が , 無視してください。スタックチェック を行わない / Gs と構造体のパックを行う / Zp は必ずつけるようにしてください いかがて、したか ? デバイスドライバを C 言語て記述するとアセンプラと比較して常 駐サイズがどうしても大きくなります。し たがって , 必要なときだけ常駐させて , 使 用後に常駐を解除するといった使い方が必 要となるて、しよう。その観点に立てば , コ マンドラインから登録 / 解除が行えるように デバイスドライバを記述することは十分に メリットがあります。 COM ファイルが生成て、きる処理系てあれ ばスタックの切り換えをなんとかすれば ( た とえばインラインアセンプリ言語やアセン プラのサプルーチンの作成などにより ) , 特集 TSR プログラミング研究 57 という原則を守ってください 「最後に常駐させたものから解放する」 ムの基本てある , といっしょに使用する場合は TSR プログラ タドライバを ADDDRV/DELDRV コマンド なお , 本バートて紹介した ESC/P プリン てみてください ) 。 応可能て、す。興味のある方はチャレンジし 処理系て、もアセンプラの助けを借りれば対 いと思います .COM ファイルが生成てきない のプログラムへの対応はそれほど難しくな

5. 月刊 C MAGAZINE 1991年7月号

RS ー 232C を使用は ワン赭ント 通信カグ弘の作成Ⅸ胤Ⅱ プログラミング 仕様の決定 上田哲ニ 講座 RS ー 232C を使用した通信プログラムを作ります。 ' 90 年 6 月号で , 2 台の PC ー 9801 を RS ー 232C で直結し端末間でおしゃべりをする TALK プログ ラムを作成しました。今回は相手のティスクのティレクトリ参照やファイ ル転送かできるような拡張を施しさらに実用的な通信プログラムを作り ます。 18 C MAGAZINE コ 1 7 第 ください。ケープルは , 直結の場合はクロ スケープル , モデム接続の場合にはストレ ートケープルを用意してください ー 232C 基本関数 PC ー 9801 の場合 , 簡単に RS ー 232C を制御す 必要なハードウェア るには , BIOS を用いる方法と MS-DOS のシ 通信の相手がいなければデータ転送など ステムファンクションコールを用いる方法 てきないのて , PC ー 9801 が 2 台必要てす。し の 2 通りあります。どちらを利用してもよい かし今回は直結型だけてなく , モデムにも のて、すが , 両方を混在して使用することは 対応するように拡張する予定なのて , もう て、きません。 1 台の PC ー 9801 を自分て、揃えなくても , 代わ , こては MS-DOS のシステムファンクシ りにモデムと電話回線とがあれば大丈夫て ョンコールを利用して RS ー 232C 制御用関数 す。 を作成してあります。関数の内容を TabIe 1 PC ー 9801 以外の機種ても主要なロジックは に , リストを List 1 に示します。関数名の下 動作するのてすが , 一部 PC ー 9801 用の MS ー にヾ PC ー 9801 専用〃と記してあるものは , 拡張 DOS 拡張ファンクションコールや I / O ポート ファンクションコールや I / 0 ポート入出力を 入出力を使用している関係て機種に依存し 使用しているのて汎用性はありません。他 てしまいました。それらの PC ー 9801 専用の関 機種に移植したい場合は , それらを書き換 数を自分の機種に合うように書き直せば異 えてください 機種間ても通信カイきます ( 私の手元には PC TabIe 1 項番 5 の受信バッフアの文字数の ー 9801 と OKI の機械があるのてすが , 少なく 取得は , ファンクションコールては受信可 ともこれらの間てはファイル転送などがて 能かどうかを調べることが直接てきないた きています ) 。 め , 代用として使用しているのて , 直接こ また , PC ー 9801 間あるいは PC ー 9801 / モデ れを調べられるような機種を使用している ム間をつなぐ RS ー 232C ケープルも用意して 人は , それに置き換えても大丈夫てす。 前回のおさらい 0t34

6. 月刊 C MAGAZINE 1991年7月号

7U ーソフトウェ 第 20 回 C プログラム画面 みなさん , このコーナーはどうも C マガ全 て少しのぞいてみましよう。 MS-C( を使用した G 凵 0 ライプラリ関数群 ) 画面作成支援ツールなどを使わずに画面 体からみて「浮いている」と思いませんか ? への変換プログラムだからで , DIVER 本体 を作成するには , 紙の上なり頭の中なりで 私は思ってます。まあいいか。浮いてるつ は言語を限定していません。 DIVER の内部 いでに PROD 旧 Y " という米国のパソコン 画面のイメージを作っておいてから , おも 表現は公開されていますし , MS ー C 変換プロ むろにコーディングに入るわけですが , 通信を知っていますか ? ほかの雑誌では ーグラムや G 凵 0 ライプラリもソースが添付さ D Ⅳ ER はその表示する画面にマウスやキー 何度か紹介されたようですが , 先日実物を れていますので , Turbo C BGI 版や BAS ℃ ポードでデータを直接書き込み , 画面を見 旧 M さんに見学に行ってきました。こいつは 版の自作も可能です。 て試行錯誤しながら画面作成ができるとい けっこうキテル ! PRODIGY は NAPLPS を 作者は「とりあえす」 MS ー C 版を作ったそう うソフトです。ここでいう画面とは普通の 全面的に使ったパソ通で , 従来のキャラク ですが , 変換プログラムが充実したらマル PC ー 9801 シリーズの 640X400 ドットの静止 タベースのものとは , はっきりいってテレ チランゲージの画面作成支援ツールになり 画面で , データはグラフィック / キャラクタ ックスとテレビ電話ほどの差 ( ? ) がありま えます。実際にはマイクロソフト言語なら す。今 , 日本でも同様のサービスを商用化 です。 他言語コールが使えますから , 主プログ させようとしているようですが , 私も一枚 マウス / キーポードで CAD やお絵描きツー ラムのソースはなんでもいいことになります。 一噛みたいよお。 ルのように書き込んだデータは , ます DIVER D Ⅳ ER を起動すると , まっさらな画面と の内部表現に従ったフォーマットでファイ ファンクションが表示されます。 DIVER の ルにセープします。このファイルを言語変 機能はすべてファンクションキーとメニュ 換プログラムで変換し , 必要な言語のソー ーで選択します。 D IVER のファンクション スファイルを得るというのが D Ⅳ ER の基本 メニューと機能は以下のとおりです。 カラー設定 ( テキスト / カラー / パレッ 的な動作です。 C ソースにジェネレートする というのは , デフォルトで提供されるのが Fig. 1 「 D Ⅳ ER 」のテモ画面 画面作成支援ツール 「 D Ⅳ ER ( G 凵 0 版 ) 」 作者 : TAKE-Q さん (PC-VAN:DLM74916, MAD i Net: MAD 1004 , ASCI ト NET pcs : S37252 ) ネット : 上記ネットほか ファイル名 : DlVER2. LZH C マガにも数多くの広告が掲載されてい る , C のソースにジェネレートする画面作成 支援ツールです。 D Ⅳ ER はけっこうよくで きていて , 市販製品を食いかねないできで す ( 広告主のみなさん , このべージにクレー ムなどっけないでくださいね ) 。しかし れがフリーソフトとは ! ひと昔前だった ら , これほどの腕を持ったプログラマなら , あっという間に会社作って大儲けしてまし たよね。時代が変わったのか , みんな余裕 で ( というか余暇で ) プログラミングしてい 、るみたいですね。 実は , 前述の C ソースにジェネレートする というのは , 間違いではありませんが正確 でもないのです。では , D Ⅳ ER がどういう 機能を持っているかを , そのあたりも含め 3 第 3 鶩 3 3 2 2 3 33 : D I VE R グラフィックの一能 36 C MAGAZINE 1991 7

7. 月刊 C MAGAZINE 1991年7月号

②の方法は DOS シェルて、通常用いられて いる方法てす。 DOS ファンクション 0 00h ~ 01 h Ah(Table 6 ) から返ってきたときの入力文字 02h ~ 03h 列の最初のコマンドが EXP ファイルて、あれ 05h ~ 09h ば , その前に RUN386 または EXE386 を挿入 OAh—ODh して , 起動するコマンドにフルバス名を付 OEh—1 1 h 加すればよいだけて、す ( Fig. 3 ) 。 12h ~ 15h ただし , DOS ファンクション 0Ah はいろ 16h ~ 17h 18h—2Bh いろなプログラムが使用しますから , COM 2Ch—2Dh MAND.COM からの要求て、あることを判別 2Eh—2Fh する必要があります。そのためには DOS フ 30h ~ 31 h アンクション 62h(Table 7 ) て、実行中のプロ 32h ~ 33h 34h ~ 37h セスの PSP アドレスを取得し , その [ 16h ~ 17 38h—4Fh h] が示す親プロセスの PSP(Table 8 ) と一 50h ~ 52h 致していることを確認します。 53h—5Bh COMMAND.COM が起動したプログラム 5Ch—6Bh 6Ch—7Fh て、あれば , 親プロセスの PSP は起動した COM MAND ℃ OM の PSP アドレスを指していま 81h—FFh すが , COMMAND.COM の場合は自分自身 を指しています。 今回紹介する exppath. c( 付録ディスク収 録 ) は DOS ファンクション 0Ah に割り込む方 法を取っています。そのため , DOS ファン クション 0Ah に割り込むタイプの DOS シェ ルとの相性があまりよくありません。 近いうちに K ト Shell などの DOS シェルが この機能を追加してくれることを希望しま す。 使用法 使用法・ exppath C-R] ( ① ) exppath 常駐する。常駐している場合には検索パ スを再設定する ② exppath —R 常駐部を解放する 常駐すると DOS ファンクション 0Ah を監 視して , EXP ファイルて、あれば , DOS-Exten der 経由て起動するように入力文字列を書き 換えます。 EXP ファイルの検索は次の順て、 行います。 ①カレントディレクトリ 80 C MAGAZINE 1991 7 オフセット 80h 04h TabIe 8 PSP(Program Segment prefix) の内容 プロクラムの終了命令 (INT 20h ) 使用可能なメモリ中の最初のセグメント 予約 内 容 DOS 機能を FAR コールするための 5 バイト (CP/M 互換 ) プログラム終了アドレス (INT 22h ) のコピー く CTRL 十 C > の抜け出しアドレス (lNT23h ) のコピー 致命的工ラーによる抜け出しアドレス (INT 24h ) のコピー 親プロセスの PSP ( DOS 非公開 ) ファイルテープル ( DOS 非公開 ) 環境変数のセグメント SP 退避領域 ( DOS 非公開 ) SS 退避領域 ( DOS 非公開 ) ファイルテープルの数 ( DOS 非公開 ) ファイルテープルへのポインタ ( DOS 非公開 ) 予約 INT 2 1 h : R ETF 予約 第 IFCB ( ファイルコントロールプロック ) 第 2FCB ( ファイルコントロールプロック ) コマンドラインの文字数通常はテフォルト DTA ( ティスク コマンドライン 転送領域 ) として使用される。 ②環境変数 EXPPATH ( 未定義ならば PATH) DOS ー Extender は RUN386. EXE, EXE386. EXE て、あれば自動的に検索します が , それ以外の場合は , 環境変数 RUN386 て、 指定してください なお , 現バージョンて、は簡単にするため , 環境変数はすべて常駐時点て、定義されてい たものを使用します。環境変数を変更した 場合は再起動してください。また , COM, EXE,BAT よりも EXP ファイルを先に検索 します。 説明 簡単に説明します ( TSR プログラムの記述 TabIe 9 chain intr 関数 (MS-C) 割り込みのチェーン #include <dos. h> VOid chain intr( handler ) 、 法に関しては本誌の特集を参照ください ) 。 ①常駐部 ( new 21 ) new 21 ( ) 関数が常駐後に呼び出される処 理て、す。この関数て、は前述のように DOS フ アンクション 0Ah を監視しており , DOS フ アンクション 0Ah が呼び出された直後に入力 された文字列を調べ , 先頭のコマンドが EXP ファイルて、あれば , DOS-Extender 経由て起 動するように入力文字列を変更しています (Fig. 3 ) 。 ・ is_command com( ) 関数で COM MAND.COM からの要求かどうかを判定 ・ getexppath( ) 関数で EXP ファイルのフ ルバス名を取得 ・ addexp ( ) 関数で入力文字列の先頭に void ( interrupt far * handler ) ( ) : チェーンする割り込み八ンドラ 割り込み八ンドラの中から別の割り込み八ンドラ han 引 e 「を起動する。 後続の割り込み八ンドラ hand 厄「を呼ぶ前にスタックと各レジスタの内容が最初に割り込みが起こった ときの状態に戻される。

8. 月刊 C MAGAZINE 1991年7月号

スを返しているだけて、す。 0 TL 入力 コンド番号 . 3 , ioctlin) 常駐を確認するための手段として , ①常駐部のデバイスへッダアドレス ②常駐チェック用の Magic No. を返しています。常駐チェック用の Magic No. は "ESCP" て、す。 IOCTL 入力は DOS ファンクション 4402 h(Table 18 ) の IOCTL キャラクタデバイスか らの制御データの受信時に呼び出されます。 今回のケースとは異なりますが , TSR プ ログラムをあえてデバイスドライバとして 記述する場合があります ( したがって , Part 1 の CON 出力ファイル化ユーティリティ (eat- con. c, 付録ディスク収録 ) をデバイスドライ バとして記述することも可能て、す ) 。デバイ スドライバて、は IOCTL 入出力て、 , ここて、示 したようにほかのプログラムと簡単に通信 て、きるため , TSR プログラムをデバイスド ライバとして記述することには十分なメリ ットがあります。普通に TSR プログラムと して記述して , 常駐を確認するための手段 を提供しようとすれば INT 2Fh システムコ ール (TabIe 4 ) に割り込む必要があります。 0 TL 出力 ゴンド番号 . 12 , ioctlout) 漢字モードと ANK モードの指定データ ( 俗 にいう漢字 IN / 漢字 OUT のコマンド ) を切り 換える機能て、す。スイッチー E の 8 通りの機能 は IOCTL 出力を呼び出して切り換えていま トヨ 〒 H 十十十十十十十十 十十十十十十十十 す。データの並びは TabIe 19 のように合計 32 バイトて、す。指定コマンドが 15 バイト未 満の場合は残りにダミーデータ ( たとえば 00 h) を追加してください リクエストヘッダの転送バイト数 が 32 バイト以外の場合は Table 20 が指定さ れたものとしてコマンドをプリンタへ直接 出力しています。これはプリンタの簡単な コマンドを直接プリンタへ出力することを 想定した機能て、す。 IOCTL 出力は DOS ファンクション 4403 h(Table 21 ) の IOCTL キャラクタデバイスへ の制御データの送信時に呼び出されます。 刀期設定 ( コマンド番号 .0 , prninit) 初期設定はスイッチー E て、指定されたプリ ンタモードに応じてプリンタを初期化して , フリーメモリ開始アドレスを返しているだ けて、す。 Turbo C/C 十十て、は _heapbase の内容 ( ワード値 ) が near ヒープ領域の先頭アドレ スを示します ( Fig. 8 ) 。また , MS ー C て、は変 数 end がスタック領域の先頭を示しています (Fig. 9 ) 。したがって , この値を指定して near ヒープとスタック領域を切り離します。 MS ー C て、は疑似変数が使用て、きないため , se gread 関数て、取得したセグメント値を使用し ただし , escptc. c ( 付録ディスク収録 ) の tsr exit 関数て、は TSR プログラムの参考のため に , 初期化処理て、返されたフリーメモリ開 始アドレスは使用せず , 直接 heap base(Turbo C / C 十十 ) または end(MS (C) まて、を常駐させています。 main 関数以降ては次のことを行っていま す。 ・前述の Fig. 13 のようにして , デバイスド ライバの追加と除去を行う。このとき内 部 FCBI ロック内のデバイスへッダのア ドレスも切り換えている。 ・常駐の確認は , DOS ファンクション 4402 h(TabIe 18 ) て、返される情報によって行 ・常駐後の再起動て、は DOS ファンクション 4403h(Table 21 ) て、スイッチー E て、指定され たモードに切り換える ( 自作プログラムて、 モードを切り換える場合はリストを参考 にしてください ) 。 ・ Turbo C/C 十十と MS ー C て、異なる部分は 常駐終了のための tsr exit 関数て、す。 MS ー C て、は疑似変数が使用て、きないため , se gread 関数て、取得したセグメント値を使用 イ main 関数以降 する。 PC59801 版 ESC[P 丿ンタドライバの説明 Turbo C/C 十十 tcc -w -mt escptc. c イルしてください TurboC / C 十十ては以下のようにコンパ TabIe 15 NEC 漢字の罫線コード ( シフト』 S : 86a2h ~ 86edh ) Table 16 新 J 旧の罫線コードと特殊記号 J 旧 2C20 2C30 2C40 2C50 2C60 0 シフト』 S E 1 F ト 2 0 ト 3 1 ト 4 2 ト 5 3 ト 6 4 ト 1 7 5 8 6 869E 86AE 86BE 86CE 86DE 9 7 ヨ A 8 L ヨ B 9 L ヨ C A ヨ D B ヨ E C ヨ F D ヨ JIS 2840 2830 2820 2260 2250 2240 0 シフト』 S E 1 F L 2 0 ト 3 1 4 2 ト 81 B E 81 CE 81 D E 849E 84AE 84BE 5 6 3 4 亠十 7 8 9 A B C D E F 5 6 7 8 9 A B C D ト丁ヨ亠十一一「 1 ト〒ヨ亠十ト T H 亠 Z 亠 十 56 C MAGAZINE 1991 7

9. 月刊 C MAGAZINE 1991年7月号

新い - ト プログラ、グ人門 C プログラマ のための 中島信行 第 1 0 回子プロセスの起動 今回は子プロセスの起動をちょっと変わった形で 取り上けます。プログラム例として , 386 マシン で動作する DOS ー Extender 用のプログラムの起動 を手助けするユーティリティを作成します。機種 依存しないユーティリティなので , 当然 FM-TO WNS でも動作します。 ターンコードを取得しています。 というような使い方をします ( system ( ) 関数 7 spawn ( ) 関数 , spawn. c て、は , コマンド名にフルバス名を の指定においてコマンドの位置て、分けて , system ( ) 関数の作成 指定する必要があるため , PATH を参照し コマンドをフルバス名て、指定する感じて、 て起動する関数を作成すると spawnp. c( 付録 MS-DOS 上の C コンパイラには , 子プロセ す ) 。この関数のポイントは DOS ファンクシ ョン 4B00h(TabIe 1 ) のプログラムのロード ディスク収録 ) のようになります。 spawnp. スを起動するために spawn ( ) 関数が用意され c て、は searchenv( ) 関数 ()S ー C), sear と実行て、す。 Fig. 1 の 8 種類の spawn ( ) 関数 ています ( ちなみに spawn( ) 関数は DOS 専用 chpath( ) 関数 (Turbo C/C 十十 ) を使用して , の関数 <ANSI 仕様て、はありません ) 。 も DOS ファンクション 4B00h を使用して , 子 PATH のリストを参照した検索を行ってい spawn ( ) 関数は引数や PATH を検索するか プロセスを起動しています。 spawn. c て、は DOS ファンクション 4B00h の ます (TabIe 3 ) 。 どうかなどの要因により , 通常 , 8 種類の関 引数をセットアップして , DOS ファンクシ 数 (Fig. 1 ) からなります。 spawnp. c は , spawnpath("chkdsk. exe", 'e: /v") : ョン 4B00h を実行し , 終了後に DOS フアノク これらの関数は機能が豊富なため , かな というような使い方になります。 ション 4Dh(Table 2 ) て、子プロセスからのリ りサイズが大きくなっています。そこて、 , spawn ( ) 関数の中身の解明もかねて簡単な Fig. 1 8 種類の spawn 関数 spawn( ) 関数 (spawn. c, 付録ディスク収録 ) を作成します。 int spawnl(int mode, char * path, char * a 「 gO, int spawnle(int mode, char * path, char * a 「 gO int spawn(cha 「 *path, cha 「 *cmd line) ; int spawnlp(int mode, char * path, char * argO, path は起動するコマンドのフルバス名 int spawnlpe(int mode, char * path, char * argO, int spawnv(int mode, char * path, cha 「 *argv [ ] ) ・ て、 , cmd line はそのプログラムに渡すコマ int spawnve(int mode, char * path, char * argv [ ] , char * *env int spawnvp(int mode, char * path, char * argv [ ] ) ・ ンドラインてす。たとえば , int spawnvpe(int mode, char * path, char * argv [ ] Cha 「 * *env spawn("a:**bin%%chkdsk. exe", "e. / (") : こまて、 76 C MAGAZINE 1991 7

10. 月刊 C MAGAZINE 1991年7月号

spawn. c, spawnp. c, system. c のプログラム を作成した本当の理由はここにあります。 switchar. c( 付録ディスク収録 ) の使用法 は次のとおりてす ( Fig. 2 参照 ) 。 Oswitchar 現在のスイッチキャラクタを表示する ② switchar [ くスイッチキャラクタ > ] スイッチキャラクタを変更する EXP 起動ユーティリティ 最近は 386 マシンも一般的になり , 仮想 8086 モードを利用したユーティリティを組み込 んて、 MS-DOS マシンとして使用しているユ AL ニ 0 ーザも少なくないぞしよう。 AL ニ 1 また , FM-TOWNS, IBM-PC, PC ー 9801 AL : 1 シリーズなどの 386 マシンて、は DOS-Extender を使用したプログラムも少しずつ増えてき ているようて、す。とくに , 京都マイクロコ ンビュータが PC ー 9801 シリーズの DOS ー Extenderf 、ある EXE386 を雑誌の付録などの 形て、配布したため , Phar Lap Software 社 の 38 引 TOOLBOX(RUN386) を購入しな くても , FM-TOWNS 用の 386 版 GCC が PC ー 9801 シリーズて、も手軽に動作させられるよ うになりました。筆者もこれを入手して , いくつかユーティリティを自作しましたが , DOS-Extender 用の EXP ファイルは MS- DOS が認識しないため , 起動がめんどうて、 7 TabIe 4 func tst. c のサイズ Turbo C 十十 1 .0 Turbo C 2 .0 MS-C 6.0 MS-C 5 . 1 コンパイラ spavvn . c, system. c をリンク 3205 バイト 3785 バイト 3212 八イト 3006 バイト 標準ライプラリをリンク 5633 バイト 6301 バイト 3730 ノヾイト 3188 バイト TabIe 5 スイッチキャラクタの取得 / 変更 DOS ファンクション 37h スイッチキャラクタの取得 / 変更 ( DOS 非公開 ) 引数 返り値 機能 AH : 37h AL : 機能コード ( 0 ~ 3 ) DL ニスイッチキャラクタ ( AL : 1 の場合 ) INT 21 h DL : スイッチキャラクタ ( AL : 0 の場合 ) AL : OFFh 工ラー スイッチキャラクタの取得 / 変更を行う。 このファンクションは AL レジスタて機能を指定する。 はティレクトリの区切り文字が ' / ' f になる。 ャラクタが ' / ' のときはティレクトリの区切り文字が ' \ ' になり , ' / ' 以外のとき スイッチキャラクタとディレクトリの区切り文字は連動しており , スイッチキ ラクタを変更する場合には次の点に注意が必要である。 スイッチキャラクタを DL レジスタて指定した文字に変更する。スイッチキャ 標準は ' / ' になっている。 スイッチキャラクタを DL レジスタに返す。 AL ニ 2 , AL : 3 は MS-DOS 2.11 専用であるため省路する。 AL レジスタに 0 ~ 3 以外のものを指定すると AL レジスタに OFFh を返す。 す。たとえば , 起動にあたっては EXP ファイルの検索は次 のようにして EXP ファイルを起動します。 exp NAME argl arg2 exp. c ( 付録ディスク収録 ) は , ユーティリティを作成してみました。 います ) 。そこて、 , EXP ファイルを起動する みて検索するようにバージョンアップして 1.00a て、は EXP ファイルも PATH のリストを としなければいけません ( EXE386 の Ver. arg2 「 u n 3 8 6 d : \ d i 「 \ N A M E. E X P a 「 g 1 Fig. 2 スイッチキャラクタ変更ユーティリティの使用例 B:*>dir * . com /w ドライプ B: のティスクのボリュームラベルは 9S10C ティレクトリは B : \ COMMAND COM VRAM COM 2 個のファイルがあります . 862208 バイトが使用可能です . B:*>switchar 現在のスイッチ・キャラクタは / です。 B:*>switchar - スイッチ・キャラクタを一に変更しました。 B:*>dir * . com -w ドライプ B: のティスクのボリュームラベルは 9S10C COMMAND COM VRAM COM ティレクトリは B : \ ①カレントディレクトリ ②環境変数 EXPPATH ③環境変数 PATH 環境変数 EXPPATH を設けたのは , 2 個のファイルがあります . 862208 ノヾイトが使用可能です . PATH の設定が長くなるのを避けるためと 検索の時間を少しても短くするためて、す。 PATH を多く定義していると PATH に定義 されているディレクトリを順に検索してい の順て、行います。 78 C MAGAZINE 1991 7