( b ) のように同じ記号定数を Human68k の仕 この仕様も , 直接ディレクトリを読み書 フィル名 様に合わせて定義してしまうのが簡単て、す。 きするようなプログラムて、は , ファイル名 MS ー C の場合は , Fig. 7 の ( c ) のように実際の の同一性を調べるときに問題になります。 Human68k のファイルシステムは , MS- 制限よりかなり大きな値が定義されていま コマンドラインの長さ DOS からほとんどそのまま拝借してきたも すから , 同じ値て、定義してやればよいて、し のて、す。 FAT やディレクトリの構造も基本 よう。また , ヘッダて、定義されているマク 的に同じて、 , 5 インチ 2HD ( 8 セクタ / 1 トラッ 口を使っていない場合て、も , どこかて、マク MS-DOS と Human68k て、はコマンドライ ク , 1024 バイト / 1 セクタのフォーマット ) の 口が定義されているはずなのて、 , その部分 ンの最大長が異なります。 MS ー DOS て、は 127 ディスクて、あれば , MS-DOS とメディアレ を修正します。記号定数を使わずに 80 とい 文字 , Human68k て、は 255 文字て、す。移植す ベルて、の互換性があるのはご存じのとおり う値がプログラム中にばらまかれている場 るプログラム中て、 , コマンドライン引数を 合は , ファイル名まわりを処理していると て、す。しかし , Human68k は MS-DOS のフ char 型の配列に複写しているときにはファ ころを探して , 該当部分を書き換えまくる ァイルシステムを完全に踏襲しているわけ イル名と同様 , 転送先の配列を拡大する必 ・・ところて、すが , 修正する箇所が多くな 要があります。コマンドライン全体て、 255 文 て、はありません。 ればなるほどまちがいが入り込む可能性が まず , ファイル名の長さの制限がありま 字まて、許すのて、あれば , 空白て、区切られた す。 MS ー DOS て、は 8 文字まて、て、すが , 高くなります。実際に限界まて、長いパス名 引数のそれぞれも 255 文字まて、取りうるとい が使われることは稀だと判断し , 無視して Human68k て、はディレクトリ項目中 , MS- ことを忘れないて、ください フ DOS て、は未使用になっている 10 バイトにフ しまうのもひとつの考え方て、しよう。手を 環境変数 ァイル名の後半を収めることて、 18 文字まて、 入れる場合は , 移植がほとんど完了してか らにしたほうが安全て、す。 午しています ( MS ー DOS との互換性の関係 て、 , 識別されるのは先頭 8 文字だけて、す ) 。 また , Human68k のファイル名として 18 MS-DOS て、は , 通常 , 環境変数名に大文 文字まで許すが先頭 8 文字しか識別しないと これはそのままフルバス名の最大長の違い 字を使い , set コマンドて、小文字の環境変数 になって現れます。パス名をメモリに格納 いう仕様は , ファイル名の同一性を確認す 名を指定しても大文字に変換されます。 するとき , MS ー DOS て、は 80 バイトのバッフ る処理て、間題になります。 れに対して Human68k て、は , システム側が アを用意すれば足りますが , Human68k て、 ファイルまわりにおける Human68k の MS 使う環境変数に小文字を使う習慣があり , ー DOS に対する拡張の 2 点目は , 小文字のフ set コマンドて、は大文字と小文字とを区別し はもう 10 バイト余分に必要て、す。 移植作業にあたっては , て、きるかぎりマ ァイル名を許すということて、す。 MS-DOS ます。また , C ライプラリの getenv, putenv クロて、つじつまを合わせて手間を省きまし て、は小文字て、ファイル名を指定しても , デ 関数については大文字と小文字を区別する よう。 MS ー DOS 上の C 処理系て、は , ヘッダフ ィレクトリに書き込まれるときには大文字 処理系が一般的て、す。 ァイルて、パス名の最大長がマクロ定義され に変換されますが , Human68k て、は小文字 さて , Human68k, MS-DOS ともコマン のまま書き込まれます。だからといって , ています。 Turbo C の場合を Fig. 7 ( a ) に示 ドの検索パスは環境変数に保持します。そ します。プログラム中て、これら定数が使わ ファイル名の大文字・小文字を区別するわ の環境変数名は MS ー DOS て、は、、 PATH 〃 , れているようなら , プログラム先頭て、 Fig. 7 けて、はありません。 Human68k て、は、、 path クて、す。あまりない Fig. 7 ファイル名の長さの制限 #define MAXPATH #define MAXDRIVE #define MAXD 旧 #define MAXFILE #define MAXEXT #define MAX PATH 260 #define MAX DRIVE 3 #define MAX D 旧 256 #define MAX FNAME 256 #define M AX EXT 256 #define MAXPATH #define MAXDRIVE #define MAXD 旧 #define MAXFILE #define MAXEXT 6 0 8 っ 0 6 9 5 ( 80 + 10 ) 3 66 ( 9 + 10 ) 5 84 C MAGAZINE 1991 6
とて、しようが , 自前て、コマンド検索パスか らファイルを探すようなプログラムを移植 するときには , 環境変数内容の取得部分を 書き換える必要があります。ほかには , 、、 PROMPT" と、 \prompt" も同じような関係 にありますが , 、、 PATH 〃以上に C プログラム から参照される機会は少ないて、しよう。 マイナーな話が続きますが , ℃ OMSPEC" について触れておきます。この環境変数は MS-DOS においてコマンドプロセッサて、あ る COMMAND.COM をリプートするときに 参照され , COMMAND.COM の絶対パス名 を保持しています。 Human68k て、はコマン ドプロセッサがリプートするなどという処 理は必要ありません。当然 , 該当する環境 変数もありません。やはり , C プログラムか ら参照される機会は少ないて、しようが , ℃ OMSPEC" という環境変数の存在と意味 だけは頭に入れておきましよう。 C からの DOS ファンクション 呼び出し くどいようて、すが , Human68k は MS-DOS を模倣して作られています。それはシステ ムコールにまて、および , Human68k の DOS コールは , MS ー DOS のそれと共通のコール 番号にほば同じ機能が割り振られています。 もっとも , MS-DOS が CP/M から引きずっ ている FCB による入出力は Human68k て、は 切り捨てられ , 該当コール番号には別の機 能が割り当てられています。また , MS-DOS のいわゆる非公開コールはごく一部を除き サポートされていません。 MS-DOS の DOS ファンクションコールは コール番号を AH レジスタに , 引数をそのほ かのレジスタに入れてソフトウェア割り込 み INT 21H を発行することて、呼び出しま す。そのため , レジスタを設定して INT 21 H を発行する関数がひとつあれば , C から簡 単に DOS ファンクションを呼び出すことが て、きます。 MS ー DOS 上の C 処理系て、は , 呼び 出し手順が簡単なかわりに呼び出せるファ Fig. 8 int k MS ー DOS ファンクションの直接呼び出し k; bdos(Ox06, Ox 幵 , 0 ) & Ox 幵 ; int k ne Oint Edition 0 P k ; lNPOUT(Oxff) ; union REGS inregs, outregs; int retval; inregs. x. ax = 0X4400 , handle , inregs. X. bX intdos(&inregs, &outregs) ; 「 etval inregs. h. ax = 0X41 ; int retval; struct SREGS sregs; union REGS inregs, outregs, Char far *fname "kill . me" / * 工ラー処理 * / if (outregs. x. cflag) { / * 工ラー処理 * / if (outregs. x. cflag) { &outregs, &sregs) ; 「 e ⅳ引 intdosx(&inregs, sregs. ds FP SEG(fname) ; inregs. X. dX FP OFF(fname); を呼び出し , プレイクチェックなしてキー 関数を使って MS ー DOS ファンクション 06H 簡単な例を Fig. 8 ( a ) にあげましよう obdos 中の関数に置き換えていきます。 見てコール番号を確認し , 該当する DOSLIB Human68k にもってくるときには , 引数を bdos や intdos が使われているプログラムを して用意しています ( いわゆる DOSLIB)0 のほばすべての DOS コールを別々の関数と うわけにはいきません OXC て、は Human68k d 。 s に相当する関数て、すべてをまかなうとい ますから , MS-DOS 上の処理系の bdos, int め込んだ F 系列未実装命令によって呼び出し クに積んて、 , コール番号を下位バイトに埋 Human68k の DOS コールは引数をスタッ 意されています。 ションに対応した intdos, intdosx 関数が用 し手順が若干繁雑て、 , より多くのファンク ンクションに制限のある bdos 関数 , 呼び出 ポードより 1 文字入力しています。 Human68 k て、は DOS コール $ FF06 に割り当てられてい る IN POUT を呼び出すことて、実現て、きま す。移植時には Fig. 8 ( b ) のように XC のライ プラリから同名の INPOUT にします。 intdos を使った例を Fig. 8 ( c ) に示しましよ う。 DOS ファンクション 44H のサプファン クション 00H を使ってファイルハンドルの装 置情報を取得しています。これは Human68 k の DOS コール $FF44(IOCTRL) のモード 0 に 対応します。 IOCTRL に関しては XC て、はモ ごとに別関数にしてあり , モード 0 に対 応するのは IOCTRLGT て、す。 intdos をこの 関数て、置き換えると , Fig. 8 ( d ) のようにな ります。 intdos の場合は , 関数の仕様を把握しない と何をやっているのかわからないと思いま すのて、 , 少し補足します。 intdos にはふたっ int retval; lOCTRLGT(handle) ; retval if ( 「 e ⅳ引く 0 ) { / * 工ラー処理 * / ・′ k Ⅲ . me ″ Cha 「 *fname int retval; retval = DELETE(fname) ; if ( 「 e ⅳく 0 ) { / * 工ラー処理 * / One POint Edition の REGS 構造体へのポインタを渡します。実 85
際には REGS は Fig. 9 のようなふたつの構造 体からなる共用体て、 , 各メンバは 8086 のレ ジスタに対応しています。共用体になって いるのは , 8086 の 16 ビット汎用レジスタ AX ~ DX が , 16 ビットのレジスタとしても , 8 ビットのレジスタふたっとしても使えるた めて、す。たとえば , AX レジスタの上位バイ トは AH, 下位バイトは AL という 8 ビットレ ジスタとして使うことがて、きます。 intd 。 s 側て、は第 1 引数て、指定された構造体 の内容をレジスタにコヒ。ーして INT 21H を 発行し , その時点て、のレジスタの値を第 2 引 数て、指定された構造体に収めて戻ります。 関数の戻り値は AX レジスタの値て、す。ま た , 結果を格納する REGS 構造体の cflag メ ンバが非 0 のときはエラーを意味し , AX に は DOS のエラーコードが入っています。た だし , MS-DOS て、はすべてのファンクショ ンがエラーを返すわけて、はなく , CP / M 互換 の ( コール番号の若い ) ファンクションて、は cflag は無意味て、す。 て、は実際の移植を考えましよう。まずコ ール番号を確認します。前述のようにコー ル番号は AH レジスタて、指定するのて、 , 引数 受け渡しに使う構造体の ah メンバに値を代 入している部分を探します 0Fig. 8 ( c ) て、は直 接 ah は現れませんが , AH は AX レジスタの Fig. 9 intdos( ) で使われる構造体 struct WORDREGS { unsigned int ax; unsigned int bx; unsigned int cx; unsigned int unsigned int Si ; unsigned int di ; unsigned int cflag' struct BYTEREGS { unsigned char al, ah; unsigned char bl' bh ; unsigned char cl, ch; unsigned char 引 , dh' union REGS { struct WORDREGS x; struct BYTEREGS h; 86 C MAGAZINE 1991 6 上位バイトて、す。メンバ ax に代入している 値の上位バイトがコール番号となります。 Fig. 8 ( c ) て、は AH レジスタに設定すべき値と AL レジスタへ設定すべき値を同時に代入し ていたわけて、す。 さて , intdos て、はセグメントアドレスを DOS ファンクションに渡すことがて、きません。 far ポインタを DOS ファンクションに渡す必 要があるときには intdosx が使われます。 Fig. 8 ( e ) に , DOS ファンクション 41H を使ってフ ァイルを削除する例を示しておきます。 こて、使用している ,FP SEG,FP OFF は far ポインタのセグメント部 , オフセット部を 取り出すマクロて、す。このふたつのマクロ を使って far* インタを分解し , それぞれレ ジスタ ( 対応した構造体メンバ ) に代入して いるわけて、す。 Human68k への移植時には こんな処理は不用て、すから , 素直に対応す る DOS コール $FF41(DELETE) て、置き換え れば , Fig. 8 ( f ) となります。 ところて、 , bdos や intdos を使わなければ DOS ファンクションが呼び出せなかったの は少し前まて、のことて、 , Turbo C 以来 , MS ー DOS 上の C 処理系て、もよく使われるファン クションについては独立した関数を提供す る傾向にあります。ここて、 , その中て、も使 用頻度の高い , MS-C の dos findfirst, dos findnext, Turbo C の findfirst, findnext を取り上げましよう。関数名は異なります が , どちらもファンクション 4EH, 4FH に よりファイルを検索し , その情報を得るも のて、す。移植時には , XC の相当関数 , FILES, NFILES に置き換えることになり ます。厳密には , 工ラー時の戻り値が , MS ー C 版て、は正の DOS ェラーコード , Turbo C 版て、は一 1 , XC 版て、は負の DOS 工ラーコー ドというように異なっていますから ( 正常終 了時はいずれも 0 を返す ) , 単純な置き換え て、は不十分なのて、すが , この違いが問題に なることはあまりないて、しよう。 実際に関数を置き換えるときには , 引数 の違いに注意します。 dos findfirst, findfirst, FILES はいずれも , 検索するファ イル名 , 検索するファイル属性 , ファイル 情報を受け取る構造体へのポインタの三つ の引数をとりますが , 引数が並ぶ順序と , ファイル情報を受け取る構造体の名前 / メン バ名が異なっています。例によって , マク ロて、つじつまを合わせることになるて、しょ う。 Fig. 10 ( a ) に dos findfirst を FILES に置 き換えるマクロ , Fig. 10 ( b ) に findfirst を FILES に置き換えるマクロをそれぞれ示し ます 0Fig. 10 て、は同時にファイル属性を表 す記号定数も , 各処理系に揃えて定義して います。 0X20 との OR を取っている部分が不 可解かもしれませんが , これは MS-DOS フ アンクション 3EH と Human68k の DOS コー ル $ FF3E ( FILES ) の仕様の微妙な違いを吸 収するためのものて、す。 MS-DOS ファンク ション 3EH て、は , 指定した検索属性に関わ らず通常ファイルは無条件に検索対象にな るのに対し , Human68k の FILES て、は , ア ーカイプビットを立てておかないと通常フ ァイルの検索が行われません。 MS-DOS と Human68k て、はほかにもファ イル属性の扱いが異なる場面が見られます。 ファイル属性を取得 / 設定する MS-DOS ファ ンクション 43H て、は , ディレクトリとポリュ ーム名の属性ビットを変更することを許し ていませんが , Human68k の DOS コール $FF43(CHMOD) て、はこれらビットも操作て、 きます。 DOS ファンクション 43H て、は , ディレク トリやポリューム名の不可視属性や読み込 み専用属性を設定するときに , ディレクト リやポリューム名を意味するビットを立て てはならないという仕様になっており , そ れを知らずに DOS ファンクション 43H を単 純に Human68k の CHMOD に置換すると , ディレクトリがファイルに化けてしまうと いうことも起こるのて、す。この場合 , 現在 のファイル属性を取得して , ディレクトリ やポリューム名のビットを保存するような 細工が必要て、す。
' 91 年 6 月号特別付録 ( 5 " 1.2M 8 セクタ / Human68k 用て、す。移植者 ( 岡田紀雄氏 ) の 本名てす ) ディレクトリへ ! 毎月 , 初心者 トラック MS-DOS フォーマット ) には , 次の のためのガイド ( 文書 ) やユーティリティな 「解を得て収録しました。 プログラムが収録されています。 どを提供するディレクトリてす。 LHAX68k のセットは LHAX68 ディレクト リに収録しました。なお Human68k 用の LHA 今月は , GCLS( グラフィック画面クリア ①付録ディスクの説明 は自己解凍ツールがサポートされていませ ツール ) , 漢字罫線変換ューティリティ ( 98 README ②高圧縮書庫管理プログラム ん。 x 形式の実行ファイルとドキュメントの →新 JIS), 半角全角変換関数 ( 本誌 4 月号「 C MAGA セミナールーム」課題の解答 ) てす。 < ディレクトリ > 圧縮ファイルというセットて、収録しました。 YLHA212 それぞれのドキュメントファイルを読んて、 , ③ X68k 版 LHA 「 LHAX68k 」 詳しくは README をご参照ください。ま こなしてください ! くディレクトリ > た , 岡田氏からの「 C マガジンの読者のみな YLHAX68 ④六角形プロック落とし「 Hextris 」 さまへ」 (YLHA68YREADME) というメッセ MS-DOS 互換指向 くディレクトリ > YHEXTRIS ージも収録しました。 , 一ください XC 「 . 2.0 ライプラリ ⑤ X68000 に移植された GNU C Compiler ② 六角形プロック落とし 本誌「 C プログラム移植の秘訣」をご覧いた くディレクトリ > YXGCC2 「 Hextris 」 ⑥「 ANSI C 言語入門講座」活用集③ だけたてしようか ? このライプラリは MS くディレクトリ > ー DOS 用の C プログラムになるべく手を加え YBOHYOH 本誌 1991 年 4 月号「フリーソフトウェア最 ⑦ MS-DOS 互換指向 XC 用ライプラリ ることなくコンパイルて、きるような環境を 新レポート」て、紹介した「 Hextris 」てす。著 Human68k 上に構築することを目的として YDOS2X くディレクトリ > 作権者 ( 斎藤靖氏 , ちりん氏 , 相沢雅陽 ( ヤ います。 ン ) 氏 ) の了解を得て収録することがてきま ⑧本誌掲載プログラム 収録したファイルは圧縮してあるのて , くディレクトリ > した。今回収録したものは FM ー R 用 , FM- YCM AGA 付録ディスクの説明 (README) に , 解凍 README を参考に解凍してからご使用くだ R の 24 ドット機用 , PC ー 9801 用の 3 種類あり 方法など , さらに詳しい説明が収録してあ ます。それぞれのファイルは HEXTRIS とい りますのて、必ずご一読ください 0README うディレクトリに圧縮ファイルとして収録 本誌掲載プログラム はテキストファイル形式てす。 MS-DOS の しました。 TYPE コマンド , あるいはお使いのエディ 詳しくは README をご参照ください。 タ , ワープロソフトて、読むことがて、きます。 : C 十十て書く単純な ~ TASK X68000 に移植された MODULA2 : Modula-2 による ~ GNU C CompiIere 高圧縮書庫管理プログラム PRAGMA : PragmaC プロジェクト : アルゴリズムと ~ ALGO 本誌「 GCC て、学ぶ 68 ゲームプログラミン 本誌 1991 年 1 月号「特集圧縮アルゴリズム MSDOS : 新 MS-DOS 入門 グ」の筆者 , 吉野智興氏のご好意により , 前 入門」て、紹介した「高圧縮書庫管理プログラ : C 移植の秘訣 DOS2H68 号収録した XGCC のソースファイルてす ( 正 ム LHA Ver. 2.12 」の公式公開版てす。著作 : 応用 C 言語 C の道具箱 OUYOU しくは前号て収録した実行ファイルのソー 権者 ( 吉崎栄泰氏 ) の了解を得て収録するこ : GCC て学ぶ 68 ゲーム X68K スに少し手を加えたものてすが ) 。 とがてきました。 LHA Ver. 2.12 のセット : ANSI C ー more ANSI XGCC 関連のソースファイルだけて、も量が は LHA212. EXE という自動解凍圧縮ファ : 明解 ANSI C 言語入門講座 MEIKAI 膨大なのて、 , 一度て収録するすることがて : スタートアップ C 十十 イルとして収録しました。 CPPJ きません。今回収録した LHA て、圧縮した複 解凍方法については README をご参照くだ : ワンポイントプログラミング O PPK 数のファイルを順次を収録していきます。 さい。解凍後に生成される LHA. I 刈 C は LHA TENSAKU : C MAGA セミナールーム 次号以降ぞもこの形式て継続して収録する 取り扱い説明書てす。 , 一読ください : 丹羽信夫の発想快発 N IWA 予定てす。 : C マガ電脳クラブ PUZZLE 「 ANSI C 言語入門講座」 X68k 版 LHA 「 LHAX68k 」 INFO : インフォメーション 活用集③ それぞれのプログラムについては関連記 ようこそ BohYoh ( [ ばうよう ] と読みます / 事ならびに各 README を参照ください。 「高圧縮書庫管理プログラム LHA 」の ( テキストファイル ) ディスク内容のお知らせ 159
ne Oint Edition 0 P C プログラム移植の秘訣 MS-DOS から Human68k へ 村田敏幸 異なる OS 間の移植には , 数々の題かプ「に行えるよとはいっても , MS-DOSi$bÆ きまとう言 MS-DOS から X68000 十 H いを日し m 68k への移植は必すしも作業第 、 man68k への C プログラム移植も例外で、が少ないわげでばないよともすれば数多 はなし man68k ば必要以上信 MS 、第あふな修正を加える単調な作業にな 00S に似せて作られており , いくつ力、の三 ~ る今回は MS ー DOS から Hum 台 n681f を塰 : ポイントさえおさえておけば比較的容易をの c プログラム移植問題を考察しよラ いうまて、もなく ,MS-DOS はインテル 8086 用の OS て、あり , Human68k は CPU にモトロ ーラ 68000 をもっ X68000 の専用 OS て、す。両 OS 間て℃プログラムを移植する場合 , CPU アーキテクチャの相違と C 処理系の相違が最 初の関門となります。 int サイズ C の int 型は , そのマシンがもっとも自然に 扱えるサイズのデータを格納てきるだけの 大きさをもちます。通常その大きさはプロ セッサの汎用レジスタのビット長に等しく , 8086 て、は 16 ビット , 68000 て、は 32 ビットて、 す。 int のサイズの違いは , 68000 から 8086 への 移植時には大問題となります。器の大きな ほうから小さなほうへ移すわけて、すから , オーパフローに注意し , 必要に応じて int を を long に書き換えるといった修正を加えな ければなりません。 逆に , 8086 から 68000 への移植時には , int のサイズの違いはさほど大きな障害にはな C PIJ りません。 16 ビット int に収まっていた値は まちがいなく 32 ビット int て、表現て、きます。 少なくともオーパフローの心配は無用て、す。 とはいっても , 世の中には 16 ビット int て、は オーパフローすることを利用したり , int と short の相互代入を繰り返すプログラムだっ てあるかもしれません。またビット操作が 絡むと , データサイズの違いが影響してく ることがあります。 典型的な例として Fig. 1 をあげましよう。 (a) は , 16 ビット int の処理系て、最下位ビット をリセットするときのごくふつうの書き方 て、す ( 変数 intvar は int 型とします ) 。しか し , このプログラムを 32 ビット int の処理系 にそのまま移植すると , 同時に上位 16 ビッ トもクリアされることになります。元の動 作を再現するためには , ビットマスクも 32 ビットにした ( b ) のように修正する必要があ るわけて、す。変数の定義自体を sh 。 rt に変更 するという対応も考えられますが , ほかの 部分とのつじつまが合わなくなる可能性が 高いのてあまり勧められません。また , 最 後の ( c ) は int のサイズによらずに同じ動作を する移植性の高い書き方て、す。 ところて、 , int のサイズが 16 ビットから 32 ビットになると , それだけ多くのメモリが 消費されます。もし , メモリ効率が問題に なるのなら , int を short に書き直すことも考 えてみるべきかもしれません。しかしプロ グラム全体に対して修正すると思わぬとこ ろて、破綻をきたすことがあります。大きめ の配列に絞って手を入れるのがよいて、しよ う。その場合は , 配列の定義部分に加え , 配列をポインタて、操作している部分も同時 に変更する必要があることも忘れずに。な お , 効率の追及は移植作業が一段落し , 動 作の確認がとれてから行うべきなのはいう まて、もありません。 工ノディアンの違い 8086 系の CPU と 68000 系て、は「複数バイト からなる整数データのメモリ上て、のバイト の並び順 ( 工ンディアン ) 」が逆になっていま す。 8086 系て、はアドレスの小さなほうに下 位バイトが格納され , 68000 系て、はアドレス の小さなほうに上位バイトが格納されます。 たとえば , 12345678H という 4 バイトデータ は , 68000 系て、は , アドレス大→ ←アドレス小 12 34 56 78 のような素直な順序て、 , 8086 系て、は , One POint Edition 81
memcpy において , 転送元と転送先の領域 が重なっている場合の動作は処理系定義て、 す。 MS-C など , 多くの処理系て、は , 領域が 重なっていることを考慮せず , 単純に頭か ら順に転送します。対して , XC の memcpy は領域の重なりを厳密に判定しますのて、 , 実行結果は異なってきます。 open 本来 , open は UNIX のシステムコールて、 す。それ以外の OS 上の C 処理系て、は , この システムコールをライプラリレベルて、エミ ュレートしていることになります。 XC の open も UNIX に似せているようて、すが ,MS-DOS 上の C 処理系ほど細部まて、気を配っているわ けて、はないようて、す。 UNIX から MS-DOS に移植されたプログラムをさらに Human68 k に移植する場合を考えて , 問題になりそう な点をあげます。 まず , 第 3 引数て、す。通常の使用において は , stat. h て、定義された S IREAD や S IWRITE といったマクロて、アクセス許可属 性を指定するわけて、すが , UN Ⅸて、は伝統的 に 3 桁の 8 進数を直接使います。左桁から順 にファイルの所有者 , 所有者のグループ , そのほかのユーザの許可属性を意味し , そ れぞれはさらに 1 ビットごとに , 読み込み , 書き込み , 実行の許可 / 禁止フラグになって います。 MS ー DOS 上の C 処理系て、はこの点を 配慮し , S IREAD, S IWRITE, S IEXEC を UN Ⅸにおける所有者の許可属性と同じ値 に揃えて定義しています。また , 下位 6 ビッ トには何の意味もケえていません。こうし ておけば , UNIX 流の書き方をしたプログラ ムも問題なくコンパイル・実行て、きます。 ところが , XC て、はこれらマクロに独自の値 を定義してあります。しかも , 下位ビット からびっしりと意味を与・えてしまっている ため , マクロを使って書き直さなければな りません。これは同じ定数を使う stat につい てもいえることて、す。 また , 第 2 引数て、も同じような間題が発生 することがあります 0MS-DOS 上の C 処理系 88 C MAGAZINE 1991 6 て、は , fcntl. h て、 , マクロ O RDONLY, O WRONLY,O RDWR を 0 ~ 2 の値に定義し ています。これも , ときに 0 ~ 2 の数字て、オ ープンモードを指定する UNIX の伝統に対す る配慮て、す。残念ながら XC て、は値が異なり ます。 malloc 有名な XC の仕様なのて、 , 確認するにとど めましよう。 XC の malloc て、割り当て可能な メモリは , 現在のヒープ領域の大きさに制 限されます。 sbrk などの関数て、ヒープを広 げることはて、きますが , あくまて、プログラ マが自分て、 sbrk を呼び出した場合にかぎり ます。 MS ー DOS 上の C 処理系て、は , ときに near ヒープと far ヒープの 2 種類のヒープ領域 をもっことがあり , near ヒープは大きさの 制限がありますが , far ヒープはメモリの許 すかぎり確保て、きます。 mall 。 c は必要に応 じて自動的にヒープを拡張するのがふつう て、す。 MS ー C て、はヒープを拡張する際の単位 をグローバル変数 amblksiz て、指定て、きま す。 また , XC 版て、は malloc に引数として 0 を 与えるとエラーになります。これは Turbo C て、も同様て、すが , MS ー C て、は malloc に 0 を与 えても正しい引数と見なされます。 exec 系 , spawn 系 一般に , exec 系関数て、は子プロセスから 制御が戻ってくることはありません。とい うのは , exec 系関数は子プロセスとして起 動するプログラムを現プロセスが占めるメ モリに読み込むからて、す。 子プロセスからは直接 , 前の親プロセス に制御が戻ることになります。 exec 系関数 の直後の行が実行されるのは , 工ラーによ り子プロセスが生成て、きなかった場合だけ て、す。また , MS ー DOS 上の C 処理系に見られ る spawn 系の関数て、は , 第 1 引数に P OVER- LAY を指定すると , exec 系関数と同じ動作 します。 XC て、も ,exec 系関数と spawn 系関数はサ ポートされていますが , spawn 系の関数のモ ne Oint Edition 0 P ードとしては P WAIT しかサポートされて いません。 exec 系て、もオーバレイは行われ ません。どちらを使っても , 必ず制御が戻 ってきます。 移植時には exec の直後て、エラーチェック をして , 工ラーて、なければ , 子プロセスか らの戻り値をもって exit て、プログラムを終了 するといった修正が必要て、す。 ただし , この方法て、は , 互いに exec て、呼 び合うふたつのプログラムがあるとメモリ をどんどん消費してしまう , という問題は 残ります。 また , MS-C の exec 系 , spawn 系関数は , オープン中のファイルのオープンモードそ のほかを環境領域を通じて子プロセスに渡 したり , 通常の実行形式ファイルだけて、は なくバッチファイルも実行て、きたりする機 能をもっています。前者については , 特定 のファイル , あるいは , Human68k Ver. 2.0 の COMMON 領域を使うことて、似たような 機能が実現て、きそうて、す ( 多分 , スタートア ップルーチンも改造することになるて、しょ う ) 。後者については , exec, spawn の呼び 出しを system に置き換えて対応することに なります。 ところて、 , XC の spawn 系 , exec 系関数 は , 無条件に環境変数 path を参照するよう て、す。たとえば , spawnv と spawnvp はまっ たく同じ動作をします。移植の障害にはな らないて、しようが , セキュリティ上は若干 まとめ の問題があるように思います。 ください 付録ディスク中のドキュメントを参照して ラリも同時に収録してあります。詳しくは MS-DOS 互換指向の XC Ver. 2.0 用ライプ はこの記事を書きながら遊び半分て、作った スクに収録します。また , 付録ディスクに ろって移植した 3 本のプログラムを付録ディ 最近の本誌掲載プログラム中からみつく
、、 far", 、、 huge" というポインタ型修飾子を使 って , たとえば , cha 「 far *p ; のように宣言します。修飾子をつけずに cha 「 * p ; と , ふつうに宣言した場合は , コンパイル 時に指定したメモリモデルによって決まる デフォルトのポインタサイズが適用されま す。メモリモデルというのは , デフォルト のポインタの種類を決めるものだと思って ください さて , 68000 にはセグメントなどという不 自然なものはありません。ポインタに near と far の区別もなければ , メモリモデルも存 在しません。長々と説明してきましたが , 移植時にはセグメントにまつわる部分をす べて無視すればよいのて、す。プログラム中 て、 near, far といった修飾子が使われていた ら , 無条件に削除します。これらは MS ー DOS 上の C 処理系て、は予約語て、あり , 同名の変数 が定義されている心配はありませんから , 工デイタなどて、すべて空文字列に置き換え てしまっても大丈夫て、す。さもなくば , プ ログラムの冒頭に Fig. 4 のような空のマクロ 定義を追加し , プリプロセス時に削除する 方法もあります。ヘッダファイルにまとめ ておき , 移植時に必ず取り込んて、もよいて、 また , セグメントとは関係ありませんが , MS ー DOS 上の C 処理系ては関数の呼び出し 規約を指定する $cdecl", $pascal" といった キーワードも追加されています。移植時に は , これらのキーワードも同様の方法て、削 除 / 無効化しましよう。 アイ、メントの間題 これは 68000 側の制限て、す。 68000 てはコ ード , データ ( バイトサイズを除く ) は基本 的に偶数アドレスに置かなければなりませ ん。奇数アドレスから 16 ビット , 32 ビット 単位てメモリアクセスしようとすると , お Fig. 5 Fig. 6 隙間のある構造体 (a) struct f00 char CI; char C2; char C3; / * 1 バイトの詰め物 * / アライメントの問題 (a) chara [ 10 ] ・ int * p = &a [ 1 ] ・ intval; ne Oint Edition 0 P struct f00 { char C; / * 1 バイトの詰め物 * / charaCIO] ・ a [ 2 ] intval & Ox 幵 ; (intval > > 8 ) & Ox 幵 ; 馴染みのアドレスエラーが発生します。も ちろん , 68000 の C コンパイラはこのあたり の事情を把握していますから ,short や int の 変数が必す偶数アドレスに置かれるよう , 必要に応じてレヾイトの詰め物を入れてワー ド境界に整合します。たとえば , Fig. 5 のよ うな char 型メンバを奇数個もった構造体て、 は , 図に示したような位置に 1 バイトの詰め 物が入ります。 ( a ) はともかく ( b ) の場合も , 構造体を配列にすることを考慮し , 末尾て、 偶数アドレスに整合することに注意してく ださい 86 系 CPU はアラインメントに関しては 68000 よりも制限が緩やかて、 , 偶数境界をま たいて、メモリアクセスしてもエラーになり ません。ただし , CPU はメモリアクセスを 2 回に分けて行うことになるため , 実行速度 は低下します。この効率低下を嫌って 86 系 の C てもデータを偶数アドレスに整合する場 合もあるようて、す。 さて , この両プロセッサの違いが移植に どのように影響するかて、すが , 移植元のプ ログラムが常識的なコーディングになって いれば , ほとんど影響しないといってよい て、しよう。すて、に述べたように いちばん 問題になりそうな構造体に関しては C コンパ イラがきちんとつじつまを合わせてくれま す。ただ , 構造体のメンバがすべて隙間な く並んて、いることを前提にするプログラム て、は問題が発生します。また , 構造体を使 えばすむところを char 配列とインデックス て、操作するプログラムになると , かなりめ んどうなことになります。 Fig. 6 ( a ) はその 後者のケースを単純化した例て、す。 char 配 列の奇数バイト位置に int データを書き込ん て、います。この場合は int のサイズとエンデ ィアンの違いまて、絡むのて、 , Fig. 6 ( b ) のよ うに修正します。 Human68k は , 外見だけて、はなく内部仕 様まて、 MS ー DOS を参考にして作られていま す。しかし , よく似ているからこそ移植時 には細部の相違に注意しなければなりませ ん。 OS One Point Edition 83
CONTENTS VOl.3 No. 6 JUN 1991 円引年 6 月一日 ( 毎月一回一日発行 ) 第 3 巻第 6 号通巻第幻号四 90 年 2 月 2 日第 3 種郵便物認可 0 COMPUTER LANGUAGE 提携記事 COMPUTER LANGUAGE 短期連載 C プログラマのための 0ne P0int Edition 応用 C 言語 新連載・ X68k 活用講座 C 言語フォーラム プログラミング添削 Conference Room 特集 実力養成講座 Programmng on Purpose ℃ ustomer serviceJ p. J. 日。。 g 。。・ C 十十で書く単純なマルチタスクカーネル Taking Controlt0 Task Mod a ー 2 によるマルチタスキング MuItitasking in Modula-2 フリーソフトウェア最新レポートく第 19 回〉自分の街を作る ! ? 野口雄平・・ Book Review ・・ プログラマのための 知的財産権概論 拡大するソフトウェア保護の実態と問題点 財ソフトウェア情報センター ・・・ 14 ・ 22 ・・ 30 ・・ 32 ・・ 34 P 耐 1 ・著作権法に見る知的財産権 / P 耐 2 ・著作権法と特許法 / P 3 ・米欧に見るソフトウェア保護の実態 オリジナル C コンヾイラ制作プロジェクト P 「 agmaC く第 7 回〉 PMI< の作成藤井保則・ アルゴリズムとテータ構造入門く第 11 回〉整列 ( 3 ) マージソート近藤嘉雪 OOP 思考の周辺く第 3 回〉手法木戸研ー 新 MS ー DOS プログラミンク入門く第 9 回〉ティレクトリの移動中島信行・ C プログラム移植の秘訣ー MS ー DOS から Human68k へ村田敏幸 ・・ 52 ・・ 58 ・ 67 の道具箱く第 12 回〉ウインドウの応用豊国永健 89 GCC で学ぶ 68 ゲームプログラミングく第 1 回〉なめらかスク。→の秘訣吉野智興・ 96 恥すかしながらドジりましたく第 19 回〉情報の省エネ化は standa 「 d に至る ( ? ) 岩谷宏・・ ANSI C ー more く第 7 回〉関数へのポインタきだあきら・ 明解 ANSI C 言語入門講座く第 3 回〉流れの制御と基本的なデータ構造柴田望洋・ スタートアップ C 十十く第 2 回〉 c 言語と c → ( 2 ) 龍崎昌平・白倉伸一郎・山本浩文・ ワンポイントプログラミング講座く第 15 回〉日付計算関数を作る上田哲ニ C MAGA セミナールームく第 10 回〉引 os プログラミング ( 2 ) 柴田望洋・・ ShortInterview X Window と DEC 円羽信夫の発想快発く第 6 回〉うまい話にこ用心・ C マガ電脳クラプ第 3 回〉九つの数が 9 に吉柄貴樹 C-MAGA News Square ・ lnformation from Compiler Makers ・ Readers' 日 00m ティスク内容のお知らせ・ EDITORS' ROOM ・本記事中のプログラム名 , システム名 , CPU 名は一般に各メーカーの登録商標です。本文中では TM. ( R ) マークは明記していません。 ・本誌および付録ディスクに掲載されたすべてのプログラムは著作権法上 . 個人で使用する目的以外で無断で複製することは禁じられています。 表紙・イラストレーション・秋山育 / デザイン・持田哲 ・ 101 ・ 105 ・・ 114 ・・ 124 ・・・ 132 ・・・ 136 ・・・ 140 ・・ 143 ・ 146 ・・ 148 ・ 156 ・ 159 ・ 160 C MAGAZINE Publisher: Masayoshi Son Publishing Director. Go 「 0 Hashimot0 Editor-in-Chief: Shinichi Hoshino Directo 「 of Marketting: Ryo Tanii Manager of sales and Advertising. yoshio Goshima Editorial and Business 0ffices: NS Takanawa Bldg. , 2-19-13 , Takanawa, M inato-ku, Tokyo 108 , Japan Editorial: Phone ( 03 ) 5488-1318 Sales : Phone ( 03 ) 5488-1360 : Advertising : Tokyo. Phone ( 03 ) 5488-1365 ()saka: Phone ( 06 ) 264-1471 Copyright ⑥ 1991 SOFTBANK Corporation. Tokyo. rights reserved. No materialin this publication may be reproduced, in whole in part, in any from without permission. printed in Japan.