2

コンピューターはすべての情報を 1 と 0/低電圧と高電圧、やだやだの形式で保存するのではないかと思っていましたが、プログラムをコンパイルすると、それまたはコンプに保存されているデータだけがバイナリ形式になります。 ...では、コンピューターは 2 つのデータをどのように区別するのでしょうか。それは 0 と 1 のストリームだけで構成されているためです...私の質問をより明確にするために、C からとてつもなく単純なコードを取り上げてみましょう:

void main() {
    int A = 0;
    int* pA = &A;
    char c = 'c';
    char* pC = &c;
    return;
}

それは何もしません - タイプ int、Int へのポインター、char、および Char へのポインターの 4 つの変数を作成するだけです...これらは 0 と 1 の形式でどこかに格納されます...では、コンピューターはどのようにそのような変数がどのビットから始まり、どこで終わるか知っていますか? まず、コンピュータにはそのアドレスがあると言うかもしれませんが、わかりました。しかし、最後はどうですか?...そして、オブジェクト/構造体のような複雑なデータ型はどうですか?

そして最後になりましたが、関数/手順はどうですか?

4

6 に答える 6

4

あなたが今読んでいる段落は、文字と句読点の流れに過ぎません。1 つの単語の始まりと終わりをどのようにして知ることができますか? 言葉の意味をどのように知っていますか。この一連のテキストは、有用な情報をどのように伝えますか?

数学についても同じことが言えます。ページに書かれた数式を見ると、それらは一連の数字と記号にすぎませんが、コンパクトな形で深いアイデアを伝える強力な方法です。そして、音楽があります。ドット、フラグ、および線のストリームは、音楽のような一時的なものをどのように表していますか?

もちろん、答えはルールがあるということです。文字はランダムに組み合わされているだけでなく、特定の順序になっています。あなたも私も知っているルールに従えば、単語を識別し、個々の意味を理解し、それらを組み合わせて考えることができます。

バイナリデータも同様です。データをランダムなビットと区別するのは、従えば意味のある方法でビットを解釈できるルールが存在することです。ここまで、さまざまな規則に関連する多くの質問をしてきました。それらすべてを説明しようとすると、このような回答で妥当なスペースよりも多くのスペースが必要になります (そして、私がその努力に費やす時間よりも多くの時間がかかります)。しかし、コンピューター アーキテクチャに関する本を手に取ると、規則、規則のしくみ、構成方法、および実装方法について詳しく説明されています。それは本当に面白いものです!

まだ実際のコンピューター アーキテクチャに飛び込む準備ができていない場合、多くの洞察を与えてくれる優れた書籍の 1 つは、Douglas Hofstadter によるGodel, Escher, Bach: An Eternal Golden Braidです。分厚い本で、アイデアがぎっしり詰まっています。しかし、それはよく書かれていて興味深いものでもあり、多くの魅力的なことを学ぶために必ずしも最初から最後まで読む必要はありません.

于 2012-04-24T16:45:25.407 に答える
3

金属にできるだけ近づくことで、これらすべての質問(およびコンピューターに関するその他の多くの質問)に答えることができます:つまり、アセンブリを学びます。これらのトピックもカバーしている本Art of Assembly(オンラインで無料で入手可能)を読むことをお勧めします。また、アセンブリ学習リソースに関する私の回答を読んでください。それでは、簡単に質問に答えさせてください。

  • コンピュータが見るのはビットの無限のストリームだけであるという点であなたは正しいです。オペレーティングシステムはファイルシステムを作成する仕事をします。ramでさえ非常に単純なファイルシステム(ページまたはセグメントがファイルである)と考えることができます。つまり、OSには、各プログラムが何を格納したか、データとは何か、コードとは何かを追跡するテーブルがどこかにあります。

  • 基本レベルの変数はバイトにすぎません。これで、次のようなステートメントを作成すると、

    a = b + 1

コンパイラは実際に任意のアドレスを変数に割り当て、このアドレスを参照するすべてのステートメントにこのアドレスをハードコードします(つまり、実際の定数(0xA3F0など)を書き込みます)。

  • データ構造体はさまざまな方法で格納されますが、c構造体について話すときは、単純です。パディングなどを無視すると、この構造体に含まれる変数が次々に格納されるだけです。そのため、構造体の長さは常にわかっています。

  • 関数は実際にはコードが格納されているメモリ内に配置されます。関数を「呼び出す」には、引数がスタックまたはその他のグローバルメモリ空間に読み込まれ、関数のアドレスにジャンプ、つまりgotoが実行されます。関数が実行されると、それを呼び出したアドレスにジャンプします(アドレスもスタックに格納されます)。

  • コンパイラーが上記の方法でコードを翻訳するという大変な作業をすべて行うことを理解することが重要です。高級言語が持つすべての機能は、作業を容易にするための単なる抽象化です。ビットとバイト、0と1、5ボルトと0ボルトだけです。

さらに、最新のアーキテクチャでは、OSだけですべてのことを実行することはできません。ハウスキーピングの多くは、ハードウェアレベルでも行われています。たとえば、メモリ管理、どのメモリアドレスがどの目的に役立つかなどです。

于 2012-04-24T16:29:31.860 に答える
2

コンピュータは知りませんし、コンピュータは気にしません。指示に従うだけです。そのような命令の 1 つは、「このアドレスから 32 ビットと、そのアドレスから別の 32 ビットを取得します。「2 の補数加算」と呼ばれる方法を使用して、これら 2 つの 32 ビット文字列を結合し、結果を最初の 32 ビットに格納します。言及された住所」。各命令は次を指定します。

  • データの読み取り元およびデータの書き込み先のアドレス

  • 読み書きするビット数

  • 読み取られたビットに対して実行される操作

コンピュータは、操作が何をするかは気にしません。コンピューターの設計者が、操作を私たち人間にとって有用なものにするのに十分優れていたというだけです。

あなたが与えるようなプログラムは、非常に高いレベルで非常に現実的です。コンピュータが理解できる形にするには、翻訳が必要です。そのような翻訳者intは、何が何であるかint *を知っており、メモリ内で何ビットを使用するか、どのコンピュータ操作を有効に適用できるかを知っています。

したがって、あなたはほとんどあなた自身の質問に答えました:

まず、コンピュータにはそのアドレスがあると言うかもしれませんが、わかりました。しかし、最後はどうですか?

始まりと長さが分かれば終わりもわかる。

より複雑なデータ構造は、通常、個々の単純な部分で構成されています。そのため、このようなコードを変換するときは、パーツを取得してオフセットを割り当て、パーツが別のパーツと重複しないようにしてから、オフセットを使用してパーツへのアクセスに使用されるアドレスを計算します。

手順と機能は複雑すぎてここでは説明できません。

ただし、最後にサンプル プログラムについて簡単に説明します。おっしゃるとおり、どうにもなりません。賢い翻訳者は、「何もしない」という命令をコンピュータに書き込むだけです。それほど巧妙でないトランスレータは、宣言した変数のそれぞれにアドレスを割り当て、2 つの命令を記述します。「この数のビットにスペースを予約します。その後、何もしません」(ビット数は、各変数を格納するために必要なスペースの長さです)。 )。コンピューターは、プログラム内の変数について何も知る必要はありません。

于 2012-04-25T08:32:41.623 に答える
2

そうではありません。同じビット シーケンスは、数値、文字列、コード、構造体などとして解釈できます。コンピューターは、一連のビットが意図されていたものを知る方法がありません。

これを試して:

int main() {
    int A = 0;
    char* pC = (char*)&S;
}

機能することがわかります。整数メモリを受け取り、それを文字配列として扱いたいと言っています。コンピューターは喜んでこれに対応します。めったに役に立ちませんが、実行できます。

異なるタイプで異なるのは、それらがどのように扱われるかだけです。浮動小数点数は、整数とは異なる方法で処理され、文字列とは異なる方法で処理されます。プログラムの低レベル バージョンを見ると、含まれるすべての操作が特定の種類のデータに固有であることがわかります。違いはビットではなく、プログラムがビットに対してどのように動作するかです。

于 2012-04-24T16:28:00.567 に答える
1

コンパイルされたプログラムは、高レベルの型を反映するパターンでデータにアクセスするマシン命令で構成されます。ほとんどのアセンブリ言語には、さまざまなサイズ (バイト、ワード、long などの読み込み) または型 (signed および unsigned integer、float および long など) のデータを読み込んで操作するためのさまざまな命令があります。コンパイラはコンパイル中に利用可能な型情報を持っているため、一貫した方法でデータを操作するコマンドを発行することにより、メモリ内のデータ (すべてゼロと 1 のみ) を適切な構造を持つものとして扱うアセンブリ命令を発行できます。型システムで。

構造体と関数については、使用している言語に応じて、多くの可能なエンコーディングがあります。私は昨年の夏にコンパイラのコースを教え、関数とオブジェクトのレイアウトに関する 2 つの講義を行いました。第1 回と第 2 回の講義のスライドは、前のリンクから入手できます。

お役に立てれば!

于 2012-04-24T16:26:45.683 に答える
0

高水準言語で言語の規則を記述し、コンパイラはその情報を作成されたプログラムに埋め込みます。CPU/プロセッサは、単なるビットであることをあまり気にしません。命令が実行されるときの非常に短い期間以外は意味がありません。加算命令の場合、ビットは加算または結果のオペランドであり、ロードまたはストアの場合、それらはアドレスまたはアドレスへのオフセットなどである可能性がありますが、直後に無意味なビットに戻ります。

別の投稿で述べたように、あなたが読んでいるこれらの単語はアルファベットの文字の組み合わせにすぎず、一度に 1 つずつ解釈される意味はありません。Web ブラウザーやピクセルを表示するビデオ カードには意味がありませんが、高レベルのユーザーにとっては、意味があります。プログラムと同じように、少しズームアウトし、プログラム全体を見てください。命令とビットの組み合わせが、変数の型を実装するプログラム シーケンスと、作成してコンパイルした高レベルのプログラム シーケンスを形成していることがわかります。

それに魔法はありません

于 2012-04-24T22:01:34.257 に答える