2016-10-21 7 views
0

今年はJavaでプログラミングを始めました。私は高レベルの概念を理解し、快適なプログラミングを感じます。低レベル抽象化の理解

しかし、私はどのように内部的にこのすべての仕事をしているのですか?私は、Javaが開発を軽減するために低レベルのものから離れてプログラマーを得るために特に作られた高水準言語であることを理解します。

本質的に、高水準言語が内部的にどのように機能するかについて詳しく知りたいと思います(オブジェクト指向プログラミングなど)。それは私には明らかですなぜ彼らはが使用されていますが、今はどのようにすべてが内部で働いています(メモリ割り当てなど)。オブジェクトは内部的にどのように表示されますか?

誰かが正しい方向にいくつかのキーワードを付けて指し示すことができますか? CやC++のような低レベル言語を学ぶことは、この学習プロセスに役立つでしょうか?

+0

コンパイルされた言語を使用すると、操作が簡単になります。あなたはCプログラムをコンパイルしてから、 'strace。/ my_program'を実行して、Linux上でシステムコールをすべて見ることができます。 libc関数が何を呼び出すのかは見事に分かり、各システムコールのマニュアルページを読むことができます(例:['read(2)'](http://man7.org/linux/man -pages/man2/read.2.html)、またはmallocの場合は 'mmap(2)'/'brk' /' sbrk'です。コードをアセンブリ言語にコンパイルする方法を見ることもできます(http://gcc.godbolt.org/)。 –

答えて

1

あなたの質問の文言に基づいて、あなたの低レベルは依然として非常に高いレベルです。

オブジェクト指向は、高さや些細なこととは関係がありません。オブジェクト指向を意味するだけでなく、オブジェクト指向アセンブリを持つことができます。基本的には言語ではなく、オブジェクト指向のどの言語でも使用できます。

メモリの割り当ては、オペレーティングシステムおよび/またはメモリを管理しているユーザーに固有です。そこには本当に高いレベルで複雑なものはありません。私はピザを持っています.3人は、3つのスライスや4つか8つのピザを切り分けることができます。それぞれの人が1つのスライスを割り当て、残りの部分があると、戻ってより多くを割り当てることができます。消費後のピザの割り当てを解放することは、私たちが視覚化したいことではありません。しかし、アイデアは同じです、あなたはプログラムが借りて/取ることを許可するいくつかのメモリがあります。それを分割して、すべての偶数のサイズにする必要はありません。さまざまなサイズの1K、2K、4K、8Kなどを提供することができます1Meg単位など、それらの倍数。誰が何を食べたのか、何が自由になったのかのテーブル/チャートを作成します。それを返すと、あなたはそれらを無料でマークします。古い学校の線形思考はこれを難しくすることができますが、MMU(メモリ管理ユニット)はこれを簡単にします。それは低レベルまたは低レベルの考え方です。彼らは、プログラムが自分のものではないメモリにアクセスするのを防ぐための保護機能とともに、アドレストランスレータです。

MMUが何をするかを簡単に見る方法は、メモリ割り当ての観点から考えると、空きメモリをすべて借りる/取ることは0x1000バイトの単位であると考えることです。アドレス0x10000から開始して、0x10000、0x11000、0x12000などとしましょう。それは実際のメモリ側の物理アドレスです。しかし、仮想アドレス空間も持つことができます。私は0x3000バイトを求めるかもしれませんし、ポインタ0x20000000を与えるかもしれません。 0x20000000と0x20000FFFの間でアクセスすると、mmuはその仮想アドレスを物理アドレス0x00007000から0x00007FFFに変換します。しかし、0x20001000〜0x20001FFFは物理的0x00004000〜0x00004FFFに変換される可能性があります。そして、自然に他の物理アドレスに0x20002000。だから誰かが10ブロックを割り当てた場合、別の3つのブロックを割り当てると、その割り当てを管理するソフトウェアが最初の10物理ブロックを最初のプログラムに与え、次の3ブロックを次のプログラムに渡すことができます。その新しい人に与えられた最初の7つのマップ、3つのフリーマップ、3つのマップが物理的な線形表示で使用されます。誰かが今4を割り当てると、私たちはそれらを仮想空間にマップすることができるので、実際にそれらを3ともう1つに与えることができます。

アルファベット順にリストされた学生のリストがある場合、寮の部屋番号が直線的に一致することを意味しません。リストのアルファベット順の学生番号1は、寮の部屋番号1に住んでいない。私は彼らの寮の部屋に自分の名前をマップするテーブルがあります。アルファベット順にリストの中央に生徒を追加すると、すべての寮の部屋番号をシャッフルする必要はなく、テーブルが必要です。だから誰かがアルファベット順のリストから5つの名前を与えられてプロジェクトに取り掛かることができます。それは彼らが5つの隣接する寮の部屋にいるというわけではありません。その5人の生徒それぞれと話す必要があるとき、それらを見つけます。仮想アドレスはアルファベット順のリストで、物理アドレスはそれらの人々が住んでいる寮の部屋です。テーブルを管理し、プログラムは線形のメモリ空間だと思うものにアクセスできますが、メモリが割り当てられて解放されると、メモリを "デフラグ"する必要はありません。 mmuなしでは、それは非常に乱雑になる。

高水準言語が回避する低レベルのものは、プロセッサのニュアンスです。私はドライブを通ってハンバーガーを注文するか、またはパン、肉、ピクルス、トマト、レタス、ケチャップなどを買って、ハンバーガーを自分で調理して組み立てることができます。高水準言語のa = b + cは1つまたは複数のレジスタをスタックに保存するための多数のメモリおよび/またはレジスタアクセスとなり、レジスタを解放してメモリに格納されている値を集めることができます前記レジスタにまだ存在していない場合)、その結果を必要に応じてメモリに保存する。印刷やファイルアクセス、ネットワークやビデオなどのシステムコール、小さなものを個別に処理して全体を作るコード。ハンバーガーのような建物を作るために必要なすべてのレンガやボード、釘やセメントなどは、誰か(コンパイラ)が建てた家を買うだけで済むか、5つのツールや材料を購入して、これらの資料を正しい順序で梳くことができます。

高水準言語は抽象化も提供します。これはCですが、私はあなたがそれを理解できると確信しています。

unsigned int fun (unsigned int a, unsigned int b) 
{ 
    return(a+b+7); 
} 
私はすべて一緒にそれを置くの漬物やナイフと一緒にレタスとパン食材とフライパンにコンパイルすることができ

:私は多くのより効率的なマクドナルドの代わりにすることができ

00000000 <fun>: 
    0: e52db004 push {fp}  ; (str fp, [sp, #-4]!) 
    4: e28db000 add fp, sp, #0 
    8: e24dd00c sub sp, sp, #12 
    c: e50b0008 str r0, [fp, #-8] 
    10: e50b100c str r1, [fp, #-12] 
    14: e51b2008 ldr r2, [fp, #-8] 
    18: e51b300c ldr r3, [fp, #-12] 
    1c: e0823003 add r3, r2, r3 
    20: e2833007 add r3, r3, #7 
    24: e1a00003 mov r0, r3 
    28: e24bd000 sub sp, fp, #0 
    2c: e49db004 pop {fp}  ; (ldr fp, [sp], #4) 
    30: e12fff1e bx lr 

脂っこいスプーンダイナー:

00000000 <fun>: 
    0: e2811007 add r1, r1, #7 
    4: e0810000 add r0, r1, r0 
    8: e12fff1e bx lr 

または私は完全に別のコンピュータ上で同じコードを使用することができます。

00000000 <_fun>: 
    0: 1166   mov r5, -(sp) 
    2: 1185   mov sp, r5 
    4: 1d40 0006  mov 6(r5), r0 
    8: 65c0 0007  add $7, r0 
    c: 6d40 0004  add 4(r5), r0 
    10: 1585   mov (sp)+, r5 
    12: 0087   rts pc 

正しいツール(gnuはうまく動作します)を使用すると、簡単にC/C++を利用して上記を見て、理解してみることができます。言語があなたのためにやっていること。 printfやファイルアクセスなどのシステムコールに関しては、アプリケーションはリンクされた他のコードであるライブラリ関数を呼び出し、最終的にオペレーティングシステムにそのタスクを実行するように要求します(キャッシュではなくそのバーガーを購入するためにクレジットカードを使用します)キャッシャーは今、箱の中のカードをスワイプしなければならない、ボックスは世界のどこかの銀行に話している。私のためにこの取引をしてください。引き出しを開けて、キャッシャーが処理します。いくつかの数字を追加するのはオペレーティングシステムには関係ありませんが、ビデオやディスクなどの制御された、複雑な、または共有されたリソースにアクセスするには、オペレーティングシステムに言語とコンパイラとオペレーティングシステム固有のものを要求する必要があります。

JavaとPython(早期パスカルなど)は、実際には実装されておらず、ハードウェアで直接実装可能なマシンコードにコンパイルすることによって、そのことを抽象化しています。次に、プラットフォームを持ち、Cのような他の言語で書かれた特定の仮想マシンを使って、それらのJavaバイトコードを読み込み、そのタスクを実行します。プッシュb、プッシュc、追加(a)ファイル。 JAVAがバイトコードレベルでどのように生成しているのかを逆アセンブルして調べることは可能ですが、コンパイルされた言語では簡単です。

javiergarvalの答えTanenbaumの本(単数または複数)は、最初は中間層、オペレーティングシステムの後にあるものをカバーするかもしれません。しかし、どれくらい低くしたいのかによって、アセンブリ言語になり、さらにロジックとバスになります。

コード:コンピュータハードウェアとソフトウェアの隠し言語 by Petzold他の方向から来る。

+0

ご連絡ありがとうございます。これは私が探していたものです。 –

0

私がお勧めする本は、Andrew S. TanenbaumのModern Operating Systemsです。

これは、プログラミングするときに気になるの方法をすべて網羅しています。

thisスレッドからです。