アプリ版:「スタンプのみでお礼する」機能のリリースについて

コンピュータ言語を学んだら、いくつもの命令が実行できると思います。

たとえば、一の二乗から、ニの二乗、三の二乗、・・・・・・・・・九十九の二乗、百の二乗までの和を求めよとか。

そのプログラムを文字記号でなく、電気信号に変えるには、どういう方法を取っているのですか。

コンパイラーという概念があるというのは聞いたことがありますが、上記の点が理解できません。

初歩的質問で恐縮です。

A 回答 (6件)

コンピュータは、機械語で動いています。



機械語とは、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」と書いてしまっただけで、動作不明のプログラムになってしまいます。
また更に、「"ループの頭"へジャンプ」というところの飛び先アドレスを間違えると、次に読み込む命令(機械語)がてんででたらめなものになり、プログラムは簡単に暴走してしまいます。

直接機械語で組むのではなく、プログラミング言語を使用することは、まずそういった原始的なミスを排除できる、と言う利点もあります。
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/12/23 12:49

>answer=110/2


>answer=55/2
ミス
55はすでに答えなので、割る必要はないですね。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2014/12/23 12:57

>たとえば、一の二乗から、ニの二乗、三の二乗、・・・・・・・・・九十九の二乗、百の二乗までの和を求めよとか。



(一の二乗)+(九十九の二乗)に距離・・・
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
と、掛け算や割り算を使わなくても、求められたことで、
以前は高速化のときよく使いましたよ。

なつかしい!

なお、これは、コンパイラーではなく
アセンブラーという、機械語(またはマシン語)のサンプルです。
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/12/23 12:55

>機械語とは、16進数のみで記述された命令・データの塊です。


見る人が便宜上見やすくするために16進数でみているだけで機械語は2進数の集まり。
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/12/23 12:51

コンパイラは、文字で書かれたプログラムを機械語に変換します。

コンパイラはツールにすぎません。
それよりもアセンブラを学ぶと、コンピュータのことが良く分かります。

こういうのを作ったことがあれば、良く分かるのですが・・・なかなか最近はむずかしいでしょうか。
http://www.gcd.org/blog/2013/11/1001/
機械語は便宜的に2進数であらわしますが、実際はメモリ内に電圧があるかないかの組み合わせで格納されます。
CPUは、メモリから電圧の組み合わせを読んで、その組み合わせに応じた動作をします。

メモリにアクセスするには、アドレスバスという複数の電線で、読みだす(または書き込む)位置を指定し、データバスという複数の電線で、データを読み出したり書き込んだりします。

CPUは何をやっているかというと、プログラムが格納されている先頭のアドレスに書かれているデータを読んで、そのデータの指示によって足し算や引き算などの仕事をします。通常はプログラムカウンタというレジスタを加算して、読みだすデータ箇所を1つ移動し、次の命令を取り出します。これの繰り返しです。

データの指示によってはプログラムカウンタを違う場所に変えろという指示がされる場合があり、これが分岐(ジャンプ)です。

なかなかうまく説明できませんね。これも参考にしてみてください。
http://itpro.nikkeibp.co.jp/article/COLUMN/20070 …
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/12/23 12:45

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

ありがとうございます。

お礼日時:2014/12/23 12:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!