あなたの質問の文言に基づいて、あなたの低レベルはまだ非常に高レベルです.
オブジェクト指向は、言語の高低とは何の関係もありません。オブジェクト指向のアセンブリを使用できます。これは言語の問題ではなく、基本的にどの言語でもオブジェクト指向の方法で使用できます。
メモリの割り当ては、オペレーティング システムやメモリを管理しているユーザーに固有です。高レベルで複雑なことは何もありません。私はピザを持っていて、3 人でそのピザを 3 切れ、4 切れ、または 8 切れなどに切ることができます。消費後にピザの割り当てを解放することは、私たちが視覚化したいものではありません。しかし、考え方は同じです。プログラムが借用/取得できるようにしたいメモリがあります。あなたはそれを分割します、すべてが均等なサイズである必要はありません. さまざまなサイズの 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 つが次の 3 つに、最初が解放された場合、誰かが 7 を割り当てると、最初の 7 つが物理的に割り当てられ、最初の 7 つが使用され、3 つが解放され、物理的な線形ビューで 3 つが使用されるというマップが提供されます。誰かが 4 を割り当てた場合、実際には 3 を割り当て、最後にもう 1 つを割り当てることができます。これは、それらを仮想空間にマッピングできるため、直線的にアクセスしているように感じるからです。
アルファベット順にリストされている学生のリストがある場合、寮の部屋番号が直線的に一致するわけではありません。リストのアルファベット順で番号 1 の学生は、寮の部屋番号 1 に住む必要はありません。私は、彼らの名前を寮の部屋にマッピングするテーブルを持っています。アルファベット順にリストの真ん中に学生を追加したとしても、寮の部屋番号をすべてシャッフルする必要はありません。テーブルが必要なだけです。したがって、誰かがプロジェクトに取り組むためにアルファベット順のリストから 5 つの名前を与えることができますが、それは彼らが 5 つの隣接する寮の部屋にいるという意味ではありません。それらを見つけます。仮想アドレスはアルファベット順のリストであり、物理アドレスは人々が住んでいる寮の部屋です。テーブルを管理すると、プログラムは線形メモリ空間と見なされるものにアクセスできます。しかし、実際には断片が散らばっているだけです。メモリが割り当てられて解放されるため、メモリを「デフラグ」する必要はありません。mmu がないと、非常に面倒になります。
高水準言語が回避する低水準のものは、プロセッサのニュアンスです。ドライブスルーでハンバーガーを注文するか、パン、肉、ピクルス、トマト、レタス、ケチャップなどを買いに行き、自分でハンバーガーを調理して組み立てます。高水準言語の a = b + c は、1 つまたは複数のレジスタをスタックに保存するための多数のメモリおよび/またはレジスタ アクセスになる可能性があるため、レジスタを解放して、メモリに格納されている値を収集できます (まだ前述のレジスターにない場合) 操作を実行するために、現在または後で必要に応じて結果をメモリーに保存します。印刷、ファイル アクセス、ネットワーク、ビデオなどのシステム コール、小さな個々のタスクを実行して全体を構成する大量のコード。ハンバーガーのような建物を作るのに必要なすべてのレンガ、板、釘、セメントなど、
高水準言語は、抽象化も提供します。これは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 (初期の Pascal など) は、実際にはハードウェアに実装されていない、またはハードウェアに直接実装できないマシン コードにコンパイルすることによって、それを抽象化します。次に、これらの Java バイトコードを読み取り、そのタスクを実行する特定の仮想マシン (C などの他の言語で記述されたもの) をプラットフォームで動作させます。タスクの一部は b をプッシュし、c をプッシュし、(a) を追加し、一部は a を読み取ります。ファイル。Java がバイトコード レベルで何を生成しているかを逆アセンブルして確認することは可能ですが、コンパイルされた言語を使用するとより簡単に実行できます。
javaergarval の回答は、Tanenbaum の本またはそのような本で、最初は中間層であるオペレーティング システムの後にあるものをカバーしている可能性があります。ただし、どれだけ低くしたいかによっては、アセンブリ言語に落ち込み、さらにロジックとバスに落ちます。
あなたは本 Code: The Hidden Language of Computer Hardware and Software by Petzold を検討するかもしれません。別の方向から来ること。