組込みシステム入門クラスを受講しています。読んでいると、キャリー ビットとオーバーフロー ビットの実装に関する興味深い質問に遭遇しました。
キャリー ビットとオーバーフロー ビットが何であるかは知っていますが、誰かがキャリー ビットを使用する状況が思い浮かびません。私が考えた理由の1つは、メモリを整列させることでした。誰かがこの問題に光を当てることができますか?
キャリー フラグは、プロセッサのアキュムレータまたはレジスタよりも広いデータに対して算術演算および論理演算を効率的に実行するのに役立ちます。これは最新の 64 ビット プロセッサでは問題にならないかもしれませんが、初期のマイクロプロセッサと一部の現在のマイクロコントローラにはまだ 8 ビットまたは 16 ビットのアキュムレータしかない場合があります。キャリー ビットは、単一のアキュムレータを使用して任意のマルチワード長の加算/減算およびシフト/回転を許可します。基本的な加算、減算、シフト、ローテート命令 (マルチワード データの操作を開始するため) に加えて、キャリー付き加算、ボロー付き減算、キャリー付きシフト、キャリー付きローテーション命令があります。 (後続の単語を操作するため)。そして、そのようなコード シーケンスを容易にするために、INC reg
とDEC reg
(ポインターおよびループ カウンターの変更のための) 命令は、算術命令であったとしても、キャリー フラグを変更 (したがって保存) しません。
一部のマイクロコントローラ (Intel 8051 など) は、キャリー フラグをシングル ビット ポート I/O 操作の読み取り先または書き込みソースとしても使用します。
キャリー フラグとオーバーフロー フラグ (プロセッサ アーキテクチャに応じて、ハーフ キャリー、サイン、ゼロ フラグなどの他のフラグも含まれる可能性があります) は、さまざまな算術演算や論理演算で設定またはクリアされます。プロセッサの命令セットは、どのフラグが存在するか、およびそれらが命令によって変更される条件について調べる必要があります。
0 から 1 を減算するとキャリー ビットが設定されるため、キャリー ビットはマシン命令で使用され、たとえば符号なし変数の less_than/greater_than 条件やループ終了条件をテストします。
また、アセンブリ言語では、加算などの算術演算のキャリーを使用して、任意精度の演算を簡単に実装できます。
キャリー ビットは、高水準言語のプログラマにはあまり見えません。
オーバーフロー ビットはめったに使用されませんが、セマンティクスで示されているように、指定された符号付き整数範囲で正確性を保証する必要がある科学的アルゴリズムで使用することができ、使用する必要があります。符号付き整数add reg1, reg2; JO exception_handler
で動作するアルゴリズムが正しい結果を生成するかどうかを効率的にテストできます。減算と整数乗算 (IMUL) にも同じことが当てはまりますが、整数除算には当てはまりません。その後、すべての (算術) フラグは未定義です。
キャリーフラグを使用するコードの簡単な例を次に示します。
int main (void)
{
unsigned int smallnum;
unsigned int largenum;
unsigned int temp_num;
printf("Enter a number: ");
scanf("%d", &smallnum);
printf("Enter a bigger number: ");
scanf("%d", &largenum);
temp_num = smallnum - largenum;
if (smallnum < largenum)
{
printf("Carry Flag SET!");
}
else
{
printf("Carry Flag CLEAR!");
}
return(EXIT_SUCCESS);
}
リストファイルを見ると、次のことがわかります。
48:carry.c **** if (smallnum < largenum)
82 .loc 1 48 0
83 0090 8B542418 movl 24(%esp), %edx
84 0094 8B442414 movl 20(%esp), %eax
85 0098 39C2 cmpl %eax, %edx
86 009a 730E jae L2
したがって、if
ステートメントは2つのオペランドの比較にコンパイルされ、その後にajae
または「JumpifAboveまたはEqual」が続きます。コマンドで使用されるテストjae
は、キャリーフラグがに等しいかどうかを確認すること0
です。どのフラグがどの条件付きジャンプに対してテストされるかを確認するには、このリファレンスを参照してください。
コードを書いているときは、リストファイルを生成し、すべての条件付きジャンプを確認します。それらの多くは、キャリーフラグの状態をチェックするためにテストしています。