CPU
 Computer >> コンピューター >  >> ハードウェア >> CPU

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

コンピュータについて最初に学ぶことの 1 つは、0 と 1 しか理解できないということです。 、 またはビット .

一方、私たち人間は 10 進法を使って数字をやり取りします。このシステムでは、0 から 9 までの数字とプラス記号とマイナス記号 (+ と -) を使用して、正または負の数を示します。

コンピュータは 2 桁しか使用できないため – 0 と 1 – 昔のエンジニアと数学者は、負の数を表し、それを使って算術を行う巧妙なテクニックを考案しました。これらのテクニックの美しさを探ってみましょう。

まず、コンピューターの仕組みに関する背景

ソフトウェア、画像、テキスト、ビデオ、数字、およびその間のすべては、コンピューターの最低レベルで 0 と 1 です。

画像、テキスト、ビデオ、および数値については、これらのものを 0 と 1 にする方法を決定するエンコード スキームがあります。たとえば、テキストの ASCII と Unicode。

私たちがコーディングするソフトウェア プログラムは、コンパイラとアセンブラを介して 0 と 1 を取得します。機械語 (または機械命令) と呼ばれる 0 と 1 のセットは、プロセッサが実行する前に、まずコンピュータのメイン メモリ (RAM) に格納されます。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由
サー ジョン フォン ノイマンによって設計されたフェッチ デコード実行サイクル。すべてのデジタル コンピューターは、このサイクルに従ってマシン コードを実行します。

プロセッサはフェッチによって実行サイクルを開始します メインメモリからの命令、次にプロセッサの制御ユニットがデコードします これらの命令は、操作コード (opcode) とオペランドの 2 つの部分に分けられます。

オペコードは、ADD (加算)、JMP (ジャンプ)、INC (インクリメント) など、実行する必要がある追加のアクションを決定します。オペランドは、その操作が実行される値 (またはメモリ位置) です。

デコードされた命令は、実行のために算術論理演算ユニット (ALU) に送信されます。 . ALU では、オペランドのオペコードに基づいて命令が実行され、結果がメモリに格納されます。

たとえば、アセンブリ コード ADD eax, 42 アセンブラによって最初に機械語 (0 と 1) に変換されます。次に、フェッチ - デコード - 実行サイクルが開始される前に、メイン メモリに格納されます。

ADD eax, 42 のマシンコードの取得時 メモリが終了すると、命令がデコードされます。デコードされた出力は、オペコードが ADD であることを示しています オペランドは eax です と 42 .

eax レジスタは、プロセッサが瞬時にアクセスできるプロセッサに組み込まれたメモリ位置です。 eax レジスタは、ほとんどのプロセッサでアキュムレータと呼ばれます。

ADD eax, 42 アセンブリ コードは、eax の現在の値に 42 を追加するように設計されています。 登録 (アキュムレータ) し、その合計を eax に格納します . eax = eax + 42です .

現在 eax であるとします。 20 です。これは、eax の値が ADD eax, 42 を実行した後 20 + 42 =62 になります。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由
EDVAC は、米国陸軍の弾道研究所用に構築された最も初期の電子バイナリ コンピューターの 1 つです。 (画像ソース、パブリック ドメイン)

EDVAC などの初期のコンピューターの設計は、面倒な数学的計算をより簡単かつ迅速に行いたいという欲求から始まりました。

コンピューターに計算させる全責任は、加算器 (2 つの数値を加算する回路) の肩にかかっています。これは、減算、乗算、除算などの高度な演算が回路内で加算器を使用するためです。

究極的には、コンピューターは論理機能を備えた高速な計算機にすぎません。バイナリ算術設計 (正の整数、特に負の整数) の課題と美しさを理解することは、コンピュータ プロセッサの最も基本的な概念の 1 つです。 .

最初に、10 進数が 2 進数でどのように表されるか、および 2 つの 2 進数値を加算する方法を見てみましょう。それから私たちは美しさを探求し始めます。

バイナリ システムのしくみ

872500 と読むように言ったら 、おそらく 872.5K と言うでしょう .私たちの心がどのようにこれを行うかを見てみましょう.

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

1 の位を右から 1 桁目に、10 の位を右から 2 番目に、100 分の 1 を 3 番目に、というように 10 の累乗ずつ増やします。

これらの各場所の 10 のべき乗は、場所の重みです。 100 位の重みは 100 です。各桁の数字にその桁の重みを掛けて合計し、完全な数を取得します。

上の図では、各場所の重みの増加が、10^0 から始まる 10 の累乗であることがわかります。 そして 10^5 を通過します .そのため、小数は基数 10 システムと呼ばれます。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

バイナリでは、各場所の重みは 2 の累乗で増加します。これは、場所の重みが 2^0 から始まることを意味します。 2^something で終わります .それが唯一の違いです。

00110101 10 進数では 53 に変換されます。コンピューターは、人間が 10 進数を解釈するのと同じ方法で 2 進数を解釈します。つまり、各桁の数字に重みを掛けて合計します。

1 と 0 を追加する方法

足し算は、10 進数で行われるのとほとんど同じように 2 進数で機能します。例を通してそれを見てみましょう。 2 つの 2 進数を追加します:1101 (13) と 1100 (12).

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

10 進法と同じように、1 の位 (2^0) から始めます。 )。 1 と 0 を足すと 1 になるので、そこに 1 を置きます。私と一緒にいれば、全体像がわかります。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

0 プラス 0 は 0 です。次に進みます。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

1 たす 1 は 2 です。2 進数の 2 は 10 として表されます。 . 1 を次の桁に繰り上げ、現在の桁の結果として 0 を保持しています。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

そこには 1 が 2 つと、前の場所から繰り越された 1 が 1 つあるので、合計 3 つの 1 があります。それらの合計は 3 になり、バイナリの 3 は 11 です。 だから 11 と書く .最終結果は 11001 になります または 10 進形式で 25、実際には 13 + 12 です。

上記の計算では、結果を格納するために 5 ビットを使用できると仮定しています。 4 ビットのコンピューターがこの加算を行う場合、結果を格納するために使用できるのは 4 ビットのみです。

その 5 番目のビットは オーバーフロー と呼ばれます 4ビットコンピュータで。整数演算では、オーバーフロー ビットは無視または破棄されます。したがって、1001 となります。 (9) 4 ビット コンピューターを使用した場合の結果として。

バイナリ演算設計の美しさ

先に進む前に理解しておく必要がある 2 つの重要な用語は、最下位ビットです。 と最上位ビット .

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

一番右のビットが最下位ビットです 場所の重みが最小であるため (2^0) )。そして、一番左のビットが最上位ビットです 場所の重みが最も高いため (2^7 ).

世界に正の数しかない場合、これでこの記事は終わりです (小数を 2 進数で表す方法と、それらを 2 進数で加算する方法を既に学習したため)。

ありがたいことに、負の数もあります。

CPU の演算設計の美しさは、ネガティブなところにあります。

では、コンピューターはどのように負の数を表し、負の数の演算はどのように機能するのでしょうか?この問題に対するエンコーディングのアプローチを見てみましょう。

以下のセクションでは、概念を理解するために 4 ビット コンピュータを使用します。つまり、5 番目のビットはオーバーフローとして扱われます。演算を行うための 16 ビット、32 ビット、64 ビットなど、すべての CPU アーキテクチャに同じ原則が適用されます。

符号マグニチュード エンコーディング アプローチ

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

1101 10 進形式では、このコード化スキームでは -5 になります。左端または最上位ビットは符号ビットです。数値の符号、つまり数値が正か負かをプロセッサに伝えます。

0 符号ビットの は正の値を表し、1 負の値を表します。残りのビットは、実際の大きさを示しています。

1101 で 、符号ビットは 1 です 、したがって、数値は負です。 101 10 進数では 5 です。だから 1101 10 進数で -5 に計算されます。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由
符号ビット符号化方式の 4 ビットで表現できるすべての数値

上の図では、このエンコーディング アプローチを使用して 4 ビットで表現できるすべての整数を確認できます。この時点まではすべて良さそうです。

しかし、よく見ると、このエンコード スキームには非常に深刻な設計上の問題があることがわかります。その問題に直面しましょう。

正の数と負の数を足してみましょう。たとえば、+4 と -1 を追加します。答えは (+4) + (-1) = (+3) になるはずです 0011 です .

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

ほら、結果は 1101 です (-5)。実際の答えは 0011 のはずです (+3)。このアプローチをプロセッサに実装する場合、この問題に対処するためにロジックを追加する必要があり、エンジニアはロジックが複雑になることを嫌います。

回路を追加すると、消費電力が増加し、パフォーマンスが低下します。

これは、最新のトランジスタ ベースのコンピューターにとっては些細な問題のように聞こえるかもしれません。

しかし、EDVAC のような初期のコンピューターを考えてみてください。EDVAC は、1 日に何百人もの人々によって操作され、キロワット単位で電力を消費する何千もの真空管で動作していました。そして政府はそれらを建設するために何百万ドルも費やしました。

当時、追加の回路と真空管を追加するには数千ドルが必要であり、メンテナンスに深刻な問題がありました。

そのため、エンジニアはよりスマートなエンコーディング設計を考えなければなりませんでした。

今こそ、この問題に取り組み、システムをよりシンプルにし、パフォーマンスを向上させ、消費電力を削減する美しさを明らかにする時が来ました.

美しいエンコーディング システムが入り、CPU が輝きます❤️

このエンコーディング スキームでは、前のコードと同様に、左端のビットが符号ビットとして機能しますが、負の数を表すためにいくつかの技術が必要です。

正の数は、前のエンコード方式とまったく同じ方法で表されます:先頭の 0 大きさの残りのビットが続きます。たとえば、このコード化スキームでも、6 は 0110 として表されます。 .

負の数を表すために、2 段階の数学プロセスが正の数で実行されます。 -6 を表すということは、+6 に対して 2 段階の数学プロセスを実行して、バイナリで -6 を取得するということです。

-6 がバイナリにエンコードされる方法を見てみましょう:

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

前の符号の大きさのアプローチでは、負の +6 を計算するには、符号ビットを 0 から変更するだけでした。 1 へ . 0110 (+6) は 1110 になります (-6).

この新しいエンコード方式では、まずビットを反転します。 0 を 1 に、1 を 0 に変更します。 0110 (+6) は 1001 になります .ビットを反転することを「1 の補数」と呼ぶので、ここでは 0110 の 1 の補数を計算しました。 結果は 1001 になります .それから...

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

0001 を追加します (+1) をステップ 1 で取得した 1 の補数 (1001) に )。結果 1010 -6 のバイナリ表現になります。このエンコード方式は、2 の補数と呼ばれます。 したがって、正の整数の 2 の補数を計算すると、対応する負の整数が得られることに注意してください。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

ビットを反転すると、1 の補数が得られます。 1 の補数に 1 を追加すると、元のビットの 2 の補数が得られます。簡単ですよね?

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由
2 の補数エンコード スキームを使用した 4 ビットで表現できるすべての数値

では、このエンコーディング スキームが非常に美しい理由を見てみましょう。 0100 を追加します (+4) と 1111 (-1).

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

ほら、2 の補数エンコード方式で正確な結果が得られます。これで、符号を気にせずに整数を追加できます。

2 の補数エンコーディングを使用して、負の整数を 0 と 1 で表現する方法を学習しました。 ADD eax, -3 を実行するとします。 eax レジスタの現在の値は -1 です。したがって、ADD eax, -3 の実行後の eax の値は -4 になります (これは 1100 です) 2 の補数エンコーディングで)。

オペレーティング システムが 1100 を取得したとき eax からユーザーに結果を提示するために、オペレーティング システムはどのように 1100 をデコードしますか? 十進数に?または、プログラマーとして 1100 に遭遇したとします。 、1100 の数をどうやって割り出すことができますか? 表す?

もちろん、1100 にいつ到達するかを確認するために、各正の整数の 2 の補数を計算し続けることはできません。 .それは遅すぎるでしょう。

プログラマーと OS は、2 の補数の美しい特性を使用して、2 進数を 10 進数にデコードします。

正の数の 2 の補数を計算すると、対応する負の数が得られます。 逆もまた然り – つまり、負の数の 2 の補数を計算すると、対応する正の数が得られます。この理由はすぐにわかります。

まず、OS またはプログラマーが 1100 をデコードする方法を理解しましょう。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

1100 の取得時 eax レジスタから、OS は 1 を認識します。 整数が負であることを知らせる符号ビットとして。 1100 の 2 の補数 1100 の正の対応物を与えるように計算されます 0100 として出力されます (+4)。次に、OS は対応する正の符号に負の符号を付加し、最終的な答えを -4 として返します。この段落をもう一度読み直すと、理解が深まります。

その後、CPU は笑顔で今日の美しさに別れを告げます;)

CPUは母親に会うために家に行きました。 2 の補数の芸術の内部の仕組みについて議論する十分な時間があります。

2 の補数エンコードが機能する理由と仕組み

+42 などの負の数を求める場合、+42 の負の数を求める最も簡単な方法は何ですか?

おそらく、最も簡単な方法は、0 から数値を引くことですよね? 0 - (+42) = -42 .これを繰り返すと、正の値 0 - (-42) = +42 に戻ります。 .これは、2 の補数が構築されるすべての数学です。

負の整数を持つマイクロプロセッサのロマンス – CPU 算術設計の方法と理由

10000 を実行しています (左端の 1 がオーバーフローであるため、10 進数で 0) マイナス 0101 (+5)。 1011 を取得します つまり、2 の補数エンコードでは 10 進数で -5 です。減算がどのように行われるかは無視してください。それは重要ではありません。 2 の補数の背後にある直感を理解することが重要です。

10000 1111 + 0001 のように記述できます (これら 2 つを追加してみると、10000 が得られます )。実際に行っていること:

        10000       -   0101
=>  (1111 + 0001)   -   0101

上記の方程式を整理すると、次のように書くことができます:

    (1111 + 0001)  -  0101
=>  (1111 - 0101)  +  0001

Step 1: subtract 0101 from 1111

        1 1 1 1
       -0 1 0 1
       ---------
        1 0 1 0
        
       see, subtracting 0101 from 1111 is equivalent 
       to inverting the bits of 0101, as we got 1010 as a result. 

  
       
Step 2: add 0001 to the above result  

        1 0 1 0  ---> result of step 1
       +0 0 0 1
       ---------
        1 0 1 1      
       
       we get 1011 that is -5 in two's complement encoding.      

2 の補数システムは基本的に 0 から数を引いたものであることがわかりましたか?ビットを反転して 1 を加算することは、0 から数を減算するための高速で賢い方法です。

これが、2 の補数を計算するときに、負の数の正数と正の数の負数を取得する理由です。これは、実際には 0 から数を減算しているためです (0 - number )。

1900 年代のコンピューターは、2 の補数符号化スキームが非常に美しく、減算が簡単に実行できるため、加算算術ロジックのみを使用していました。

たとえば、100 から 12 を引くには、CPU が +12 の 2 の補数を計算して -12 を生成し、次に 100 に -12 を足して、必要な出力を得ます。

0 から直接減算して、2 進数で負の数を見つけたり、その逆を行ったりしないのはなぜですか?

引き算は時間がかかり複雑なプロセスなので (借用のおかげです)、その方法を使用する場合、コンピュータには高価な引き算回路が必要になります。負の整数を表現するたびに 0 から減算することを想像してみてください。私たちにとっても、コンピューターにとっても悪夢になるでしょう!

2 の補数エンコーディングは、よりパフォーマンスの高いソリューションであり、回路設計が単純になり、多くの費用を節約できます。これは、減算に高価な回路が必要なく、+ と - の整数の演算を処理する追加のロジックがないためです。単純な足し算で、足し算と引き算の両方を行うことができます。

では、この美しいエンコード スキーム (2 の補数 ❤️) について、コンピューター デザイナーに感謝しましょう。

最後の言葉

私は、自分が作成した教材に対して決して料金を請求しないと自分に約束しました。単純な記事であれ、コースであれ、電子ブックであれ、私が教育のために行うことは、常に 100% 自由でオープンです。

Twitter アカウントで役立つリソースを投稿し、有意義な考えを共有しています。この記事から何か新しいことを学んだ場合は、私をフォローして DM を送ってください。それは私の一日を作るでしょう:)

すべての開発者、すべての作成者、すべての人間が誰かから学びます。私たちが学ぶ人々やリソースは引用され、広められるべきだと私は信じています。これにより、それらの善良な人々が私たち全員のためにもっと多くのことをするようになります.これが私の良いものです。

mycodeschool の Animesh は、こ​​の記事で書いた概念を含め、他の誰よりも多くのプログラミング概念を教えてくれました。

私のメンターであり友人である André Jaenisch のレビューと絶え間ないサポートがなければ、この記事を書くことはなかったでしょう。

楽しく学習しましょう!


  1. Redis SADD –セットに要素を作成して追加する方法

    このチュートリアルでは、コマンド– SADD を使用して、キーに格納されている設定値に要素を作成および追加する方法について学習します。 redis-cliで。キーがデータストアに存在する場合、指定されたすべての要素がセットに追加されます(すでに存在する要素は無視されます)。そうでない場合は、セットに追加する前に新しいセットが作成されます。 redis SADDコマンドの構文は次のとおりです:- 構文:- redis host:post> SADD <key name> <value 1> [ <value 2> ] 出力:- - (integ

  2. Windows 10 の自動再生オプションにアクセスして操作する方法

    Windows にある最も古い機能の 1 つ オペレーティング システムは AutoPlay と呼ばれます . Windows 98、Windows XP から存在しています 次に Vista まで 、Windows 7 Windows 8、Windows 8.1 に引き継がれました そして今、Windows 10 に ! ただし、Windows のごく一部にすぎません ユーザーは、Windows を 1 つでも保存できるこの重要な機能に注目しています。 USB フラッシュ ドライブなどのポータブル ストレージ デバイスからのウイルスにマシンが感染するのを防ぎます。 およ