素人さんにアセンブラとコンパイラの違いを説明するのは無理か

Yaizawa さんという人が 嘘書いて 高木先生に怒られてたので、彼の云う『初心者に分かりやすいように方便を使った』というのをまじめにやってみた ・ω・

普通の開発では、プログラマが書いたソースコードを「コンパイラ」というプログラムでCPUが理解できる命令に変換します。CPUは素早く動けますが基本はおばかなので、計算とかコピーとかしかできません。コンパイラはソースコードを単純な命令に変換します
コンパイラは危険な動きをするプログラムを作ってしまわないように一応気をつけて作られているので、ウイルスのような変な動きをするプログラムはあんまり作りません。
アセンブラの場合は、コンパイラが作り出すようなCPUに理解させるプログラムを直接書きます。なのでコンパイラのように安全装置がないので危ないことを普通に書けます。

プログラム言語によってコンパイラは別々なので、C++とC#のコンパイラは別物です。アセンブラはCPU命令を書くので、IntelのCPUとモトローラのCPUのアセンブラ命令の書き方は全く別で、片方読めれば他のも何となく分かるなんてものじゃないです

まず、これがツイッターの原文

普通の開発では、プログラマが書いたソースコードを「コンパイラ」というプログラムでCPUが理解できる命令に変換します。CPUは素早く動けますが原始的な命令しかないので、1つの命令で、計算や代入や単純な入出力(画面を1点光らせるとか、プリンタで1文字表示する、キーボードから1文字読む)などしかできません。コンパイラはソースコードをコンピュータのわかる原始的な命令に変換します
特定のことをさせようとしたプログラムはコンパイラに通すと、汎用ライブラリというひな形のようなものがあるので、よく知られた悪意のあるコードをコンパイルに通すと、ヒューリスティックアルゴリズム(あいまい検索のようなもの)があるウィルス対策ソフトならば検出できることがあります。
アセンブラの場合は、コンパイラが作り出すようなCPUに理解させる命令を直接書きます。コンパイラのようなライブラリがないので、同じことをするプログラムを書いても、人が違えば全く別のものになり、危険なプログラムでも、検出することが難しくなります。

一方、コンパイラはプログラムが終わったらちゃんと制御が戻ってくるように (スタックポインタ(プログラムが戻ってくる場所)などの)管理をコンパイラがしているので、安全にプログラムできますが、アセンブラは自分で管理しなくてはいけないので、(おろそかにすると)簡単にパソコンがフリーズするようなプログラムになってしまいます。

プログラム言語によってコンパイラは別モノなので、C++とC#の(ソースは似ていますが)コンパイラ(が出力するプログラム)も別物です。

アセンブラはCPU命令を書くのですが、CPUにも種類(アーキテクチャー)があります。たとえば、代表的なものに Intel 系 と モトローラ系 と ARM 系 があってかなり違います (ただ、片方読めればなんとなくならわかるレベルだとは思う )

とりあえず最初の文章と同じ用語レベルで正しく書き直してみた。

初心者に分かるように…といっても誤解を招くようなことかいちゃだめだと思うんだ。

言いたいことはわかるんだけどね・ω・;

コンパイラは確かにプログラムがちゃんと最初の制御に戻ってくる安全装置のようなものを実装してるのだけど、この文章を見ると、コンパイラを通すと ウィルスは開発できないようにしか見えないよね。

あと、コンパイラの違いについて、C++とC#を例に挙げてるけど

できるプログラムは、VBと C++ 、および VB.NET と C#は 似てるけど、 C++とC#で別物だったり、ソースは C++とC、および VB と VB.NET では似てるって 関係も 説明しないと、コンパイラが別物って説明も不十分なのかも
(基本的にVB やC/C++はあまり、Runtime(実行するときに必要なライブラリファイル)に依存しないプログラムをつくれますが、C#やVB.NET は.Net Framework専用のプログラムを作るコンパイラ)

コンピュータ以外を例に説明するなら、新しい薬を開発するのに、原子をひとつひとつを組み合わせて、ウィルスに効くか試すのがアセンブラ、 アミノ酸単位で組み合わせて試すのが コンパイラという感じだろうか ・ω・

アセンブル使うコンピュータウィルスの製作者って、全部アセンブラで書くわけじゃなくて、コアの部分をインラインアセンブラという、C言語などへのアセンブラを埋め込む技術を使って、汎用的な部分はC言語で書いてると思うので、「ウィルス製作者はアセンブラで書く」って関連ツイートも見かけたけどちょっと違うと思う

おまけ

では「コンパイラ」「アセンブラ」という言葉に初めて触れた江川紹子さんに、「標準ライブラリ」「リンカ」などを交えてgets()とfgets()の違いをどのように説明すればよいかご指導頂けますか? 私には無理でしたので、あえて方便を使いました

「標準入力」じゃなくて「標準ライブラリ」なのだろうかとか思ったり
なんで、gets と fgets なんだろう …。
(gets は昔標準入出力ライブラリ関数だったけど削除されたとかいう話?)

gets に データを入れる 箱の大きさと 入れる方法 を(ファイルやキーボードから)指定できるのが fgets。
逆に fgets のデータを入れるサイズを指定せず、標準入力(通常キーボード)からデータを受け取るのが gets 命令。

だったと思うのだけど、初心者に gets と fgets の違いを説明するというシチュエーションがよくわからないのだった・ω・;

おすすめ

8件のフィードバック

  1. 名無し より:

    ニーモニックだのマシン語だの、やったこと無い人には判りません。
    そうなってくると、インラインアセンブラなんて分からないだろうし、(今の開発環境は判りませんが)やれデバッガて云々や逆アセンブル(今はもう無いのかな)して・・・なんて説明しても疲れます。
    相手せずに黙っているのが無難だと、私個人は思います。

  2. 名無し より:

    ニーモニックだのマシン語だの、やったこと無い人には判りません。
    そうなってくると、インラインアセンブラなんて分からないだろうし、(今の開発環境は判りませんが)やれデバッガて云々や逆アセンブル(今はもう無いのかな)して・・・なんて説明しても疲れます。
    相手せずに黙っているのが無難だと、私個人は思います。

  3. 元教育実習生 より:

    厳密には正しくなくても、初めて聞く人間でも分かるように教える、というのが現代の教育の姿ではないでしょうか…。
    過剰に高度化した専門分野を、多少正確性は犠牲にしても、その目的や内容を一般人に分かりやすく伝える、というのも専門家に求められる役割かと思います。大変ですが。

  4. 元教育実習生 より:

    厳密には正しくなくても、初めて聞く人間でも分かるように教える、というのが現代の教育の姿ではないでしょうか…。
    過剰に高度化した専門分野を、多少正確性は犠牲にしても、その目的や内容を一般人に分かりやすく伝える、というのも専門家に求められる役割かと思います。大変ですが。

  5. 名無し より:

    コンピュータウィルスの話が出ているってことは、
    「バッファオーバーランアタックを防ぐためには、gets 関数ではなく fgets 関数を使うべき」
    というような発言をして、
    「どう違うの?」って聞かれたんじゃないですかね?

  6. 名無し より:

    コンピュータウィルスの話が出ているってことは、
    「バッファオーバーランアタックを防ぐためには、gets 関数ではなく fgets 関数を使うべき」
    というような発言をして、
    「どう違うの?」って聞かれたんじゃないですかね?

  7. 名無し より:

    一連のやりとり、Twitter上をリアルタイムで閲覧していました。
    どうも、Yaizawaさんはトロイとワームを区別せずにご説明されているようでした。
    gets()とfgets()の説明が必要となり、コンパイラが気をつけるというのはワームへの対策でしょう。
    分からなければ聞き直すことができる環境において、分かりやすくするために嘘を交えるというのは不適当であると考えます。
    たとえ話を用いるなら、それこそよく使われる、日本語と英語、それと翻訳者の例を挙げた方が分かりやすいのではないでしょうか。

  8. 名無し より:

    一連のやりとり、Twitter上をリアルタイムで閲覧していました。
    どうも、Yaizawaさんはトロイとワームを区別せずにご説明されているようでした。
    gets()とfgets()の説明が必要となり、コンパイラが気をつけるというのはワームへの対策でしょう。
    分からなければ聞き直すことができる環境において、分かりやすくするために嘘を交えるというのは不適当であると考えます。
    たとえ話を用いるなら、それこそよく使われる、日本語と英語、それと翻訳者の例を挙げた方が分かりやすいのではないでしょうか。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です