基本的な質問かもしれないのですが:
●プログラミング言語をコンパイルしたらマシン語になるのでしょうか?
●マシン語になるとしたら、なぜ、Windowsのgccでコンパイルした実行ファイルはUnix上で動かないのでしょうか?
C言語などのプログラミング言語は人間が理解できる言葉で書かれていて、これをマシン(例えばIntelのCPU)が理解できる言葉に変換するのが「コンパイル」だと今まで私は理解していました。だから、IntelのCPU上でコンパイルした場合、他のCPUでは動かないのだと納得していました。
しかし、IntelのCPUが理解する言葉になるのであれば、WindowsでコンパイルしてもUnixでコンパイルしても IntelのCPUの言葉になっている点で変わりがないような気がします。しかし、Windowsでコンパイルした実行ファイルはUnixでは動かないですよね。私は根本的な勘違いをしていると思うのですが、それが何かを教えて頂けると幸いです。
No.9ベストアンサー
- 回答日時:
#3です。
> コンパイルした実行ファイルは
> (1)CPUに直接働きかける部分
> (2)OSの機能を使って、間接的にCPUに働きかける部分
> の両方を持っているのでしょうか?
他の方も書いていますが、実際のプログラムが動作する場合においては、両方が混じっています。
(2)の部分のイメージとしてですが、例えば
void main() {
printf("hello world");
}
といったプログラムを実行した場合を考えます。
これを実際に実行した場合、Unixではコンソール、Windowsではコマンドプロンプトに文字が出力されるわけですが、このそれぞれの画面に文字を出力する、という処理は各OSの機能によるものになります。
こういった部分があるため、OS依存性がでることになります。
また、stdio.hなどの基本機能とOS機能のなかだちをする処理が、コンパイルの中でもリンクといわれる処理になります。(・・・で、よかったと思います。)
No.10
- 回答日時:
>OSとのリンクが文字通り「リンク」なのですね。
ちょっと違います。
リンクとは複数のオブジェクトファイルを一つの
実行ファイル(exe)にまとめる事です。それは標準ライブラリーかもしれませんし
複数のソースファイルがあるなら、それらをまとめる処理の事です。
「リンカ C言語」で検索してみてください。
http://www.cqpub.co.jp/try/kijidb/yougo/san.htm
http://asfa.tokyo-u-fish.ac.jp/joho991/C-gen.htm
参考URL:http://www.cqpub.co.jp/try/kijidb/yougo/san.htm,http://asfa.tokyo-u-fish.ac.jp/joho991/C-gen.htm
No.8
- 回答日時:
確かに、IntelのマシンでコンパイルしたらIntelのマシンの機械語が出力されますが、
実行ファイルの形式というのはそれぞれののOSによって違います。
WindowsでもCOM形式(今どきはあまりききませんが)とEXE形式がありますよね。
Unix系とかでもa.out形式とかelf形式とかあります。
それは、実行ファイルを各OSでどのようにメモリ上で実行できるように展開するかが違うからです。
もちろん、APIなどOS毎の機能を使っていても、動かないのは、他の方もおっしゃっているとおりです。
それは、たとえば、Windowsでも
95でしか動かないNTでしか動かない実行ファイルがあるのと同じことです。
この回答への補足
> WindowsでもCOM形式
> (今どきはあまりききませんが)とEXE形式がありますよね。
> Unix系とかでもa.out形式とか
> elf形式とかあります。
> それは、実行ファイルを各OSでどのように
> メモリ上で実行できるように展開するかが違うからです。
なるほど、たしかにそうですね。
分かりやすい例をありがとうございます。
No.7
- 回答日時:
#1、#4です。
特殊なものを除いて実行モジュールにはヘッダー(OS毎に形式が決まっている実行モジュールの最初の部分)が有ります。OSはこの部分を見ただけで実行できるかどうかを形式的に判断できます。ドライバもまた然りです。
No.6
- 回答日時:
>gcc でC言語をコンパイルする時、たとえばライブラリとして stdio しか使わない場合、OSに依存する機能は使っていないような気がするのですがそういう問題ではないのでしょうか?
たとえstdio.hを使わなくてもコンパイル後の実行ファイルはOSによって形式が違うので、OS依存だと思いますね。それはUnixであってもBSDとLinuxでは互換性ないでしょう。それに、プログラムの実行処理(main関数に行くまでの処理)はOSがやりますしメモリ管理もOSですからOSが違えば同じCPUでも互換にはならないと思います。
ちなみに、OSと実行ファイルの間にエミュレータを入れて、OS間の差を吸収してやれば、バイナリ互換になります。
No.5
- 回答日時:
>gcc でC言語をコンパイルする時、たとえばライブラリとして stdio しか使わない場合、
>OSに依存する機能は使っていないような気がするのですがそういう問題ではないのでしょうか?
標準ライブラリの実装そのものはOSに依存しますよね。
>コンパイルした実行ファイルは
>(1)CPUに直接働きかける部分
>(2)OSの機能を使って、間接的にCPUに働きかける部分
>の両方を持っているのでしょうか?
両方ですね。
>つまり、、OS間のドライバの違いが機種依存を生み出している、と思って良いのでしょうか?
だけではありません。
根本的なところで、そのOSが実行ファイルとして起動可能なフォーマットのファイルになっていることが大前提です。
Windows用のコンパイラでコンパイルしたならWindows用の実行ファイルのファイル形式に基づいてマシン語に翻訳されますし、UNIX用のコンパリラならUNIX用のファイル形式に基づいて翻訳されます。
つまり、
int main()
{
int a;
a = 1 + 2;
return 0;
}
なんてプログラムから生成されるマシン語がOSが異なっても同一なものが生成されるとしても、OSが実行ファイルと認識できなければ動かすことが出来ません。
この回答への補足
>両方ですね。
これは、言われてみれば確かに。OSが実行ファイルと認識する必要がありますね。
(1)CPUに直接働きかける部分
(2)OSの機能を使って、間接的にCPUに働きかける部分
の両方が exe ファイルに含まれているというのはなかなか驚きでした。
No.4
- 回答日時:
> すると、機能など呼び出しているだけで、直接CPUに命令しているわけではないのでしょうか?
機能などを呼び出している部分、直接CPUに命令している部分など混在していると思います。機能などを呼び出している部分があればそのOSに依存している つまり、他のOSでは実行できないものとなります。
No.3
- 回答日時:
コンパイル=マシン語に直接変換する形ではありません。
実際には、そのコンパイルを行なうソフトの実装によりますが、基本的にはそのOSなり、ソフトウェア上で直接動作できる形式への変換を行ないます。
Windowsにしろ、Linuxにしろ、OS上ではコンピュータ全体を管理する為のソフトウェアが既に動いており、これらを有効に活用しながら動作するよう、コンパイルを行ないます。
これらのソフトウェア(デバイスドライバ)がOSによって異なるので、ソースは同じでも、コンパイル後のファイルは、環境依存が発生することになります。
この回答への補足
ありがとうございます。ちょっと分かったような気がします。
つまり、、OS間のドライバの違いが機種依存を生み出している、と思って良いのでしょうか?
ちょっと根本的な疑問が出てきました。
コンパイルした実行ファイルは
(1)CPUに直接働きかける部分
(2)OSの機能を使って、間接的にCPUに働きかける部分
の両方を持っているのでしょうか?
それとも(2)だけなのでしょうか?
No.2
- 回答日時:
コンパイルしたら、「コンパイルした部分」のマシン語ができあがります。
が、このままではプログラムとしては動作しません。コンパイルした部分で使われている関数呼出などを外部のライブラリと結合してやる必要が有ります。(リンク)
(もうひとつ、プログラムを動かすための前準備の部分、後準備の部分も場合によってはくっつけてやる必要が有ります。)
この、コンパイルした後にくっつける、前準備、後準備や、関数等の呼出かた(どういう名前のライブラリをどういう手順で呼び出して使うか)が、OSによって異なります。
ということで、コンパイル(+リンク)する時に想定したOS上でしか、プログラムは動作しません。
この回答への補足
ありがとうございます。
>コンパイルした部分で使われている関数呼出などを
>外部のライブラリと結合してやる必要が有ります
gcc でC言語をコンパイルする時、たとえばライブラリとして stdio しか使わない場合、OSに依存する機能は使っていないような気がするのですがそういう問題ではないのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
<unistd.h>をVisualStudioでつ...
-
アプリケーションのDLLファイル...
-
c言語です コンパイルした時に...
-
すべてのリビルド: 0 正常、 0 ...
-
共有ライブラリの内容確認について
-
VS2010環境で2点ほど質問
-
C#で char型とstring型の比較で...
-
実行後にコンパイルに失敗しま...
-
「インクルードファイル 'pthre...
-
Delphiでクラスをオブジェクト...
-
C言語で作ったらWindowsでもMac...
-
GDIエラー
-
fatal error LNK1112
-
define文のパラメータを実行時...
-
Visual studio2022 コンパイル...
-
プレコンパイルの意味を教えて...
-
gcc コンパイル killed
-
バージョンの違うライブラリを...
-
[COBOL] ソースの復帰
-
Visual Basic.NETの処理速度は6...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
アプリケーションのDLLファイル...
-
<unistd.h>をVisualStudioでつ...
-
すべてのリビルド: 0 正常、 0 ...
-
lhafileをインストールしたい
-
C#で char型とstring型の比較で...
-
gcc コンパイル killed
-
[COBOL] ソースの復帰
-
c言語です コンパイルした時に...
-
実行後にコンパイルに失敗しま...
-
共有ライブラリの内容確認について
-
ビープ音が鳴りません・・・
-
gcc バージョン違いによるコン...
-
64ビットのlinuxで32ビットメモ...
-
NASMとMASMの違い
-
C言語で作ったらWindowsでもMac...
-
math.hに含まれる関数が使えない
-
MVSマシンで0C7でABENDしたので...
-
ccとgcc
-
「インクルードファイル 'pthre...
-
自作DLLの中身を暗号化
おすすめ情報