• ベストアンサー

(初歩の初歩) CPUとプログラミング言語

コンピュータ言語を学んだら、いくつもの命令が実行できると思います。 たとえば、一の二乗から、ニの二乗、三の二乗、・・・・・・・・・九十九の二乗、百の二乗までの和を求めよとか。 そのプログラムを文字記号でなく、電気信号に変えるには、どういう方法を取っているのですか。 コンパイラーという概念があるというのは聞いたことがありますが、上記の点が理解できません。 初歩的質問で恐縮です。

質問者が選んだベストアンサー

  • ベストアンサー
  • asciiz
  • ベストアンサー率70% (6630/9393)
回答No.3

コンピュータは、機械語で動いています。 機械語とは、16進数のみで記述された命令・データの塊です。 CPUは1バイト~数バイトで構成される命令を取り出し、解釈、実行、また次の命令を取り出し……ということを繰り返します。 機械語では、 ・CPUで持っているレジスター(データの入れ物)へ値を入れる ・レジスター同士の演算(加減算等)を行う ・指定アドレスへジャンプ ・レジスタ値をチェックしたフラグにより条件分岐する ・メモリを読む、書く ・I/Oを通じた読み出し、出力 などが行えます。 一つの命令の実行が終わればまた次にある命令を取り出し……と、順々に実行していくのが、コンピュータの基礎原理です。 いわゆるWindowsの「exeファイル」の中身は、この機械語の塊でできています。 しかし、バイナリエディタでexeファイル内の16進数を見たところで、機械語の羅列が何を表しているか、人間が見てもすぐに解読できるものではありません。 (exeファイルには、純粋な機械語以外にも、exeファイルの構造を表すデータや、文字列データ・バイナリデータ等が含まれているのですが。) 16進数で表された8ビット、または16ビットのうち、何ビットかが命令種別を表し、何ビットかで操作するレジスタを表したりしているのですが、これを覚えるのは相当な苦労を強いられます。 そこで、人間に読みやすい形でプログラムを記述できるようにしたのが、「プログラミング言語」です。 プログラミング言語は、一定のパターンで機械語に変換できる構造になっています。 例えば、1から4までを足すC言語のプログラムは、次のように書けます。 for (int x=1,y=0; x<5; x++) {y+=x}; これを機械語に直すと、例えばこんな感じになります。 アドレス1000のメモリを変数x用に確保 アドレス1004のメモリを変数y用に確保 CPUレジスターAに1を代入 アドレス1000にレジスターAの値をコピー CPUレジスターAに0を代入 アドレス1004にレジスターAの値をコピー :ループの頭 ※ラベルは機械語にならない レジスターAにアドレス1000の値を取り出す レジスターAを数値5と比較する 5以上の場合、"ループ脱出"へジャンプ アドレス1004にレジスターAの値を加算する レジスターAの値を1増やす アドレス1000にレジスターAの値をコピー "ループの頭"へジャンプ :ループ脱出 ※ラベルは機械語にならない こうすると、"ループ脱出"までプログラムが実行された時、アドレス1004のメモリ上に、10という値(=1+2+3+4)が入り、計算できたことになります。 たった一行のCプログラムが、(ラベル行を除き)13組の機械語(※本当は一つ一つの命令が、16進数になっている)で、ようやく実行できることになります。 ---- 上記でわかったかもしれませんが……機械語のできることは、非常に原始的です。 わかりやすい変数名は、ありません。(「メモリ上の指定アドレス」となって、無くなります) ループの範囲を表す括弧も、ありません。 サブルーチン名・関数名なども無く、呼び出しアドレスがあるだけです。 この、ないないづくしの言語を使って、正常に動くプログラムを作るのは、機械語を読む以上に大変なことになります。 ですから、人間に分かりやすい(そしてミスの起きにくい)、プログラミング言語が考案され、プログラミング言語を使って、プログラムを組むようになったわけです。 ---- プログラミング言語は、一定の規則で機械語に変換できるように構成されています。 「人間寄りの言語によるプログラム」を、「コンピュータで実行できる機械語列」に変換することを、コンパイルと言います。 コンパイルされた結果の機械語列は、直接機械語で組むよりも、(実行)効率の悪いことは多々あります。 しかしそれでも、「変数名」「サブルーチン」「関数の組み合わせ」など、(機械語よりも)高度なプログラミング概念を使用することができ、大幅な開発効率の向上に結び付いています。 また、直接機械語で組んだ場合、「アドレス1004」とすべきところを、うっかり「アドレス1000」と書いてしまっただけで、動作不明のプログラムになってしまいます。 また更に、「"ループの頭"へジャンプ」というところの飛び先アドレスを間違えると、次に読み込む命令(機械語)がてんででたらめなものになり、プログラムは簡単に暴走してしまいます。 直接機械語で組むのではなく、プログラミング言語を使用することは、まずそういった原始的なミスを排除できる、と言う利点もあります。

adviceanswer
質問者

お礼

詳細な御回答に心より感謝申し上げます。本も一冊買って勉強しようと思います。

その他の回答 (5)

回答No.6

>answer=110/2 >answer=55/2 ミス 55はすでに答えなので、割る必要はないですね。

adviceanswer
質問者

お礼

ありがとうございます。

回答No.5

>たとえば、一の二乗から、ニの二乗、三の二乗、・・・・・・・・・九十九の二乗、百の二乗までの和を求めよとか。 (一の二乗)+(九十九の二乗)に距離・・・ 1~99なので、99をかけて、2で割るだけで、求まりますね。 1+2+3+・・・10なら。 answer=(1+10)*(10)/2 answer=(11)*(10)/2 answer=110/2 answer=55/2 沢山書けばいいわけでもないので、そこは、センスもあるでしょうね。 CPUには小さなメモリのレジスタという物がありますが。 x86で・・・久しぶりだ~(最近マシン後でまともに書くことなかったですからね) ;ax=start ;bx=end ;return ax bitween_calc: push bx push cx add ax,bx mov cx,bx mul cx shr ax pop cx pop bx ret みたいなかな。。超久しぶりなので、ニーモニックが相当怪しい。 あと、ほとんどのインラインCからの呼び出しだと、AX,BXくらいは壊してもOKだったりするので、 BXをスタックする必要もないのですが。 mulは掛け算 shrは本来はレジスタを左右に回す命令なのですが、 右に回すと値が半分になるため、2固定の割り算としてよく使われました。 (古い時代のやり方ですが) 2固定の掛け算は、左回りにすればOKです。 0x0110=6 r<<1 は 0x1100 つまり、12 r>>1 は0x0011 つまり、3 と、掛け算や割り算を使わなくても、求められたことで、 以前は高速化のときよく使いましたよ。 なつかしい! なお、これは、コンパイラーではなく アセンブラーという、機械語(またはマシン語)のサンプルです。

adviceanswer
質問者

お礼

お忙しいなか、どうもありがとうございます。

回答No.4

>機械語とは、16進数のみで記述された命令・データの塊です。 見る人が便宜上見やすくするために16進数でみているだけで機械語は2進数の集まり。

adviceanswer
質問者

お礼

有難うございます。感謝申し上げます。

noname#215107
noname#215107
回答No.2

コンパイラは、文字で書かれたプログラムを機械語に変換します。コンパイラはツールにすぎません。 それよりもアセンブラを学ぶと、コンピュータのことが良く分かります。 こういうのを作ったことがあれば、良く分かるのですが・・・なかなか最近はむずかしいでしょうか。 http://www.gcd.org/blog/2013/11/1001/ 機械語は便宜的に2進数であらわしますが、実際はメモリ内に電圧があるかないかの組み合わせで格納されます。 CPUは、メモリから電圧の組み合わせを読んで、その組み合わせに応じた動作をします。 メモリにアクセスするには、アドレスバスという複数の電線で、読みだす(または書き込む)位置を指定し、データバスという複数の電線で、データを読み出したり書き込んだりします。 CPUは何をやっているかというと、プログラムが格納されている先頭のアドレスに書かれているデータを読んで、そのデータの指示によって足し算や引き算などの仕事をします。通常はプログラムカウンタというレジスタを加算して、読みだすデータ箇所を1つ移動し、次の命令を取り出します。これの繰り返しです。 データの指示によってはプログラムカウンタを違う場所に変えろという指示がされる場合があり、これが分岐(ジャンプ)です。 なかなかうまく説明できませんね。これも参考にしてみてください。 http://itpro.nikkeibp.co.jp/article/COLUMN/20070404/267378/

adviceanswer
質問者

お礼

詳しい御回答ありがとうございます。感謝申し上げます。

回答No.1

http://www.usamimi.info/~geko/arch_acade/elf00b_digital/index.html すべての基本は回路。この集合体。 電気のON/OFFが1と0。だからコンピュータが理解できるのは2進数だけ。

adviceanswer
質問者

お礼

ありがとうございます。

関連するQ&A

  • プログラミングについて。

    コンピュータは電圧の高い(H)と低い(L)を2進数としてCPUがクロック信号の入力を受けて処理します。 2進数はそのままだと扱いづらいので、数値的に親和性のある2のn乗進数を使います。 一般にコンピュータは1オクテットを1バイト、1ワードとしています。 その時16進数2桁で1バイトとなることから16進数表記が使われています。 なので、極論で言えば16進数2桁ではなく256進数1桁でも良かったという事です。 実は、大抵のアセンブリ言語は2進数表記を扱えます(8進数も使えるかも)。 アセンブラは16進数でも2進数でもそのまま対応するマシン語に置き換えていくものです。 アセンブリ言語とマシン語は一体一で対応しているので、実行ファイルがあれば、逆アセンブルで完全なアセンブリコードを復元出来ます。 マクロアセンブラの場合はマクロ命令までは再現されませんが、ここでは関係無いので割愛します。 つまり、マシン語とアセンブリ言語は本質的に全く同じものです。 単に、人間に読みやすく見せているものアセンブリ言語です。 マシン語もアセンブリ言語も低水準言語です。 高水準言語とは、C言語などのコンパイルを必要とするものや、BASICやJavaScriptのようにインタープリタを必要とするもののことです。 こちらは、CPUが直接解釈できるマシン語とは全く違う人間の都合に合わせた表現でコーディングし、後からマシン語に変換する仕組みのものです。 人間に読みやいコードをマシン語に変換するので、関係は一体一ではありません。 つまりコンパイルやインタープリットすると元の情報(ソースコード)は失われます。 で、① インタープリタとインタープリットとは何でしょうか?教えていただけないでしょうか?すみません。 ② マクロアセンブラの場合はなぜマクロ命令が再現されないのでしょうか?教えていただけないでしょうか?すみません。 ③ 実行ファイルがあれば、逆アセンブルで完全なアセンブリコードを復元出来ます。とはどういう事でしょうか?つまり、実行ファイルというのは、プログラマーが書いたソースコードのことでしょうか?教えていただけないでしょうか?すみません。 教えていただけないでしょうか?すみません。

  • なでしこのプログラミングについて。

    僕は今、日本語プログラミング言語「なでしこ」でプログラム(と言っていいほどのものではない)を作っています。そして、どうしてもやり方がわからないところがあります。 「、」や「。」、括弧などの記号または字の文字数を、打った文字列から数えさせ、言わせたいのです。 どうか、やり方もしくは、命令文そのものを教えていただけないでしょうか。 本当に宜しくお願いします。

  • プログラミングの第一歩・教えて下さい

    Windowsで動くプログラムを作る際・・・・ プログラム言語のCDを購入する必要がありますか? プログラムはどこに書くのでしょうか?メモ帳?ワードパッド?MSワード?プログラム用ソフト? 書いたプログラムに名前をつける際の拡張子は何にしますか? どこに保存しますか?Cドライブですか? ほんの初歩の初歩で恐縮です。

  • プログラミングの第一歩 基礎の基礎

    C言語でのプログラミングを勉強したいと思っています。周りで教えてくれる人もいるのですが、いきなり話がプログラミング言語の初歩に入るので、よく理解できません。コンピュータとは無縁の文科系の私にもわかるように、初歩以前のABCを教えていただければうれしいです。 プログラミング自体は、書物を読めば分かると思います。ただ、ワードパッドなりメモ帳なりに組んだプログラムを実際にマシーンに読ませて動作させるようにするにはどうしたらいいのでしょうか。 Windowsの初期画面から、どこに入っていってプログラムを入力しますか? プログラムの保存先はCドライブですか? どうやって、そのプログラムを実行しますか? 恥ずかしながら、このレベルが分かりません。適切なサイトも見当たりません。 どうぞ宜しく教えて下さい。

  • プログラミング(C言語)の勉強について

    情報系の大学1年生です。現在C言語のプログラミングの授業を受けています。 前期C言語の基礎を勉強したのですがいまだによくわかりません。 と、いいますのは、基礎の基礎のプログラムの書き方はわかりますが、難しくなると自分で書けないということです。 授業の課題が自力でできないので、友達のを写させてもらい(ほんとはいけないことはわかっています)、とりあえず提出し、あとでそのプログラムを理解する、というやり方で前期はなんとか乗り越えました。 現在、授業はアルゴリズムに入り、ますます授業についていけなくなり、情けない話ですが友達の書いたプログラムすら理解できないという状況です。 しかし、このままではまずいという思いと、もっと自分で思ったようにC言語を使えるようになりたいという思いから、今質問させていただいています。 C言語の入門書(柴田芒洋・明解 C言語入門編)を読んでいてもパソコンの知識が乏しいため、メモリや処理系など、何がどうなっているかわかりません。 ・C言語を理解するためにはある程度のパソコンの知識は必要ですよね? ・こんな私にも理解できるようなわかりやすい書籍はありますか? 今の自分の能力から考えて、授業の課題を一人でできるとは思いません。もちろん自分で書く努力はしていますが、コンパイルの時点で大量のエラー、実行してもきちんと結果がでません。エラーが出ればまだ修正できますが、実行しても結果がでない場合、自分でミスを見つけられません。 ・友達のプログラムを見せてもらって、後で理解するという勉強法には問題があると思っています。しかし、抜け出すにはどうしたらいいのでしょうか? ・本で勉強しても自分で書いてみなければ身につかないと思っているのですが、何からやればいいんでしょうか?ちなみにプログラムを書く環境はあります。 まとまりのない質問で恐縮ですが、ご指導よろしくお願いします。

  • プログラミングを突き詰めて考えると難しい

    プログラミング(C.C++)を勉強しているのですが、プログラムが実行されるまでの流れの”中身”が分かりません。 ■C言語で書いたプログラム ↓ ■コンパイラ ↓ ■マシン語 ↓ ■CPU だと思うのですが中でどのように処理されているかがよく分かりません。 あと、「マシン語によるプログラミングでは、基本的にCPUが直接解釈できるマシンコードと一対一に対応するニーモニックを使用する。この後アセンブラによってニーモニックをマシンコードに変換し、CPUで実行できるようにする。」と書いてるあったのですが、C言語との違いは何なのでしょうか?どちらもマシンコードに変換するのでおなじプログラムだと思うのですが。 色々調べているうちにこれを理解していくにはかなり難しく、マシン語がどのようにCPUで処理されて結果としてでてくるまでの過程など勉強しなければいけない気がするのですが、わかりやすい参考になる本やサイトがれば教えて頂けないでしょうか

  • アセンブリ言語は原始プログラムですか?

    質問(1) アセンブリ言語というのは、 add $S1, $S2 みたいなやつですよね? wikipediaで「ソースコード(ソースプログラム、原始プログラム)」の注釈1,2を読むと、 注1:【機械語の命令に記述するアセンブリ言語(アセンブラ)が存在するが、このアセンブラ用の文字列で記述されたプログラムはソースコードとは呼ばれないのが普通である。】 注2:【アセンブリ言語で書かれたプログラムはソースコードと呼ばれない】 と書かれてあります。 でも、 他の教材では アセンブリ言語で書かれたプログラム(原始プログラム) と書かれています。 どっちが正しいのでしょうか? 質問(2) 目的プログラム(オブジェクトプログラム)とは、 IT用語辞典によると 【オブジェクトプログラムとは、ソースプログラム(人間が認識できるプログラム言語で高水準言語など?)をコンパイラで機械語に翻訳したプログラムのことである】 とありますが、 ソースプログラムをコンパイラで翻訳するとアセンブリ言語になるんではないのですか? そのアセンブリ言語をアセンブラで翻訳して機械語になるのではないのでしょうか? どなたかご教授ください。 お願いします。

  • linuxからC言語のコンパイラー使えますか?

    仕事でunixからC言語のコンパイラーをつかっています。 WindowsXPからC言語となるとすぐVISUALC++を想像してしまい 単純なunixでつかっているようなものが見当たりません。 linuxはつかったことないのですが、unixと似ているとききました。 unixと同じく標準でcコンパイラーは付属しているのでしょうか? ちなみにC言語を使いテキストファイルを編集(並び替えやあるワードの抜き出しやあるワードの置換)するプログラムを組み実行しています。

  • C言語を記述しましたが、実行する方法がわかりません

    softbank社の明解C言語入門編というテキストで プログラムのさわりを学ぼうと思い同書を購入しました。 書いてあるプログラムをそのとおり記述して実行し、覚えるという ものです。 一番はじめは /*   整数値15と37の和を表示する */ #include <stdio.h> int main(vid) { printf("%d", 15+37); /*整数値15と37の和を10進数で表示 */ return (0); } 上記を実行すると、実行結果 52 となるそうなのですが 上記プログラムをワードパッドに記述して、list0101.cとして 保存しました。 このあと、どのような作業で、実行結果が表示されるのかが わからないのです。テキストにも実行としか書いてありません。 ど初心者で恐縮ですが、検索したところマッチするアンサーが なかったため、質問させていただきます。 よろしくお願いいたします。

  • C言語 コンパイラ プログラム プログラミング

    ・テンパズル Ten Puzzle ttp://www014.upp.so-net.ne.jp/arigirisu/TenPuzzle.html ・初心者のためのポイント学習C言語 ttp://www9.plala.or.jp/sgwr-t/detail/EnvSet.html ・OSはWindows8 現在、上記のページを参考にテンパズルというプログラムを作成しています。 しかし、上記のページに紹介してあるコンパイラだとテンパズルのソースが実行されません。 なので、どのコンパイラを使用すればよいのでしょうか? 最初はVisual Studio 2012を使用しようとPCにインストールしましたが、使用方法が良くわからず検索してもうまく出てきません。どちらの回答でも構わないのでお願い致します。

専門家に質問してみよう