C言語関係掲示板

過去ログ

No.325.MS-DOSのCとWindowsのC?

[戻る] [ホームページ]

No.2025

MS-DOSのCとWindowsのC?
投稿者---おすぎ(2002/07/09 19:43:50)


よろしくお願いします。
ハンディターミナルで作られたMS-DOSのCをWin98や2000で動かしたいのですが、
MS-DOSのCとWindowsのCとでは書き方が違うと聞きました。
現在VC++でコンパイルしているのですが、
MS-DOSのCをVC++でコンパイルしてWindowsで動かすことは
可能なんでしょうか?
先日Cを始めたばかりで右も左も分からない初心者です。
どなたかご存知の方、お教え願いますm(__)m

No.2027

Re:MS-DOSのCとWindowsのC?
投稿者---B.Smith(2002/07/09 21:21:55)


こんばんは。

>ハンディターミナルで作られたMS-DOSのCをWin98や2000で動かしたいのですが、
>MS-DOSのCとWindowsのCとでは書き方が違うと聞きました。
>現在VC++でコンパイルしているのですが、
>MS-DOSのCをVC++でコンパイルしてWindowsで動かすことは
>可能なんでしょうか?
>先日Cを始めたばかりで右も左も分からない初心者です。

可能ですが、Visual C++を使用する方法は初心者の方にはお勧めできません。一応、参考程度に注意点等を簡単に説明しておきます。

MS-DOSのアプリケーションをWindowsに移植する場合、ある程度慣れが必要です。手間を掛けたくないのであれば、まずは16bitコンパイラを入手してコンパイルし、問題があるようならば16bit→32bitの移植を行う、という手順にした方が良いかもしれません。
(Microsoftのコンパイラは、バージョンの違いで16bit、32bitを区別出来ます。No.1981を参照してください)

MS-DOSのプログラムは、16bitのコンパイラでそのままコンパイルすれば、基本的にはWindows上でも動作します。Windowsでは、16bitコンパイラで生成された実行ファイルは、プロテクトモードの配下にある仮想8086モードで動作するようになっています。
Visual C++等の32bitコンパイラの場合は、生成されるコードはプロテクトモードで動作させるようになりますので、標準入出力や純粋なアルゴリズム以外の部分(ハードウエアを直接制御している部分)の変更が必要になります。ちなみにグラフィックもハードウエアを直接制御しています。

・MS-DOSでは、ハードウエアに近い処理やシステムサービス等はint86やoutp等の関数を使用して制御しましたが、Windowsでは、これらの関数は存在せず、すべてWin32 APIを呼び出す形になります。MS-DOSのプログラム内に存在する割り込み処理やI/Oポート制御を、すべてWin32 APIに置き換えなければなりません。

・インラインアセンブラ等で割り込みを行っている場合も、同様にWin32 APIを利用する形に置き換えなければなりません。インラインアセンブラでは、文法に問題がなければコンパイル時に警告等のコンパイルエラーが表示されませんので、注意が必要です。
テスト.
#include <stdio.h>

void    SetCursor(int ,int );

void main(void )
{
    SetCursor(5,10);
    printf("%d\n",Idx);
}

void    SetCursor(int Column,int Row)
{
    _asm{
        mov     dl,byte ptr [Row]
        mov     dh,byte ptr [Column]
        xor     bh,bh
        mov     ah,2
        int     10h
    }
}

このテストプログラムは、カーソル位置をビデオBIOSにより変更するものです。このプログラムは、16bitコンパイラでコンパイルした場合は問題なく動作します。Visual C++等の32bitコンパイラでも問題なくコンパイル出来ますが、割り込み処理を行っているので、プログラムを実行するとAccess Violationにより強制終了してしまいます。

・16bitコンパイラではint型は16bitですが、Visual C++でコンパイルしたものは32bitになります。int型を16bitとして扱っている部分があるならば注意が必要です。

・32bitアプリケーションのアドレス空間は、32bitのフラットアドレッシングです。16bitアプリケーションにおけるセグメントの考え方は必要ありません。そのため、near、far等は使用する必要はありません(ポインタは32bitになります)。



No.2029

Re:MS-DOSのCとWindowsのC?
投稿者---おすぎ(2002/07/09 23:30:20)


こんばんは。
早速詳しいご説明ありがとうございますm(__)m
こんなに詳しく説明していただいて光栄です。
サンプルソースまで書いていただき、とてもよく分かりました♪

 とりあえず、16bitから32bitへ変換できる
コンパイラを探すことにします。自分で解析して
Cを書いてる時間も知識も持っていないので・・・。

 本当にありがとうございました。
また何かあればよろしくお願いいたしますm(__)m


No.2043

Re:MS-DOSのCとWindowsのC?
投稿者---B.Smith(2002/07/10 13:39:22)


こんにちは。

> とりあえず、16bitから32bitへ変換できる
>コンパイラを探すことにします。自分で解析して
>Cを書いてる時間も知識も持っていないので・・・。

(No.2030)
>16bitから32bitへ変換するコンパイラがどうしても
>見つかりません。もう出回ってないのでしょうか?
>どうしても仕事で使わないといけないので、

16bitから32bitへ変換するコンパイラというものは存在しないかもしれません。

参考までに、Visual C++ではサンク(thunk)を利用する、という方法があります。これは、16bitの処理を32bitアプリケーションから、あるいは32bitの処理を16bitアプリケーションから呼び出すための方法です(詳細はMSDNライブラリを参照してください)。「変換」というよりも、移植を容易にするための機構、と解釈した方が良いと思います。
サンクを利用する場合、16bitの処理は16bitコンパイラで生成しなければならないので、結局16bitコンパイラも必要になります。

時間が無い、ということですので、とりあえず、以下の方法を提案します(前提として、PC上でハンディターミナルのアプリケーションが実行出来ることを目的としています)。

前の開発環境が残っているのであれば(普通は残しますが)、そこでPC用にコンパイルすれば、その実行ファイルはWin32上でも動作します。
また、ハンディターミナルのCPUがPCと同系列のものであり、標準入出力しか使っていないプログラムであるならば、ハンディターミナル用に作成した実行ファイルでも、PC上で動作するはずです。
ただし、ハンディターミナルのアプリケーションが販売品として作成されたものである場合は、標準入出力しか使っていないというのは考え難いところです。

前の環境が残っていなければ、とりあえずそのままVisual C++でコンパイルしてみて、問題個所はその都度修正します。回りくどい言い方ですが、これは移植作業の事です。手間が掛かることを覚悟しなければなりませんが、運がよければそれほど修正しなくても済むはずです。

16bit版コンパイラを入手してコンパイルします(Microsoftの16bit版C/C++コンパイラはVisual C++ 1.51以前のものです)。
現在では業務で通用するような16bit版コンパイラの入手は困難だと思いますので、あまり現実的でないかもしれません。

アプリケーションの使用目的は分かりませんが、単純に「ハンディーターミナルで行っていた(I/Oを含まない)処理をPC上でも行いたい」というのであれば、元のソースプログラムから目的の処理部分を抽出し、それを基にPC版を作成する、といったことも考えられます。イメージとしては、「新規にPC版を作成する」という感じですが、PCのプログラム作成に慣れている技術者の場合は、単純な移植よりも、新規で作成した方が早い場合があります。

P.S.
No.2027のテストプログラムはおかしいですね。
        ・
        ・
        ・
void main(void )
{
    SetCursor(5,10);
    printf("%d\n",Idx);    /* ← この部分 */
}
        ・
        ・
        ・

このプログラムを試してみる場合は、関数SetCursorの直後に適当な文字列を表示してください。




No.2054

Re:MS-DOSのCとWindowsのC?
投稿者---おすぎ(2002/07/11 20:00:30)


B.Smithさん、とても分かり易い説明ありがとうございます。
32Bit時代のPCしか知らない私にとっては、
ちょっと創造しにくい世界の話になってしまいましたが、
全貌は掴めたように思います。

解決策もたくさん提示していただきまして、
本当に感謝しています。ただ、やはり一番硬い方法と
なると、やはり△硫魴荳になるような気がします。
しかし、どう足掻いても今の私の技量では、
とても納期までに移植作業をしてる時間がないので、
悔しいですが、外注を使うかスポットで誰かに頼むかしか
ないのかも知れません・・・。
B.Smithさんのように分かる方を探すのが一番確実で
早い方法かも知れませんね(^_^;)

 いろいろご丁寧にありがとうございました。
これにめげず、少しづつでもC言語を勉強していきたいと思います。
また何か行き詰まったらご教授お願いいたします。
ありがとうございましたm(__)m