Assembly-programming-assembly-registers

提供:Dev Guides
移動先:案内検索

アセンブリ-登録

プロセッサの操作には、主にデータの処理が含まれます。 このデータはメモリに保存され、そこからアクセスできます。 ただし、制御バスを介してメモリストレージユニットにデータ要求を送信し、同じチャネルを介してデータを取得するという複雑なプロセスを伴うため、メモリからデータを読み取り、メモリにデータを保存すると、プロセッサの速度が低下します。

プロセッサの動作を高速化するために、プロセッサには registers と呼ばれる内部メモリストレージの場所がいくつか含まれています。

レジスタには、メモリにアクセスすることなく処理するデータ要素が格納されます。 限られた数のレジスタがプロセッサチップに組み込まれています。

プロセッサレジスタ

IA-32アーキテクチャには、10個の32ビットと6個の16ビットプロセッサレジスタがあります。 レジスタは3つのカテゴリに分類されます-

  • 汎用レジスタ、
  • 制御レジスタ、および
  • セグメントレジスタ。

汎用レジスタは、さらに次のグループに分けられます-

  • データレジスタ、
  • ポインターレジスター
  • インデックスレジスタ。

データレジスタ

4つの32ビットデータレジスタは、算術演算、論理演算、その他の演算に使用されます。 これらの32ビットレジスタは、3つの方法で使用できます-

  • 完全な32ビットデータレジスタとして:EAX、EBX、ECX、EDX。
  • 32ビットレジスタの下半分は、4つの16ビットデータレジスタとして使用できます:AX、BX、CXおよびDX。
  • 上記の4つの16ビットレジスタの下半分と上半分は、8つの8ビットデータレジスタとして使用できます:AH、AL、BH、BL、CH、CL、DH、およびDL。

データレジスタ

これらのデータレジスタの一部は、算術演算で特定の用途があります。

  • AXはプライマリアキュムレータです*。入出力およびほとんどの算術命令で使用されます。 たとえば、乗算演算では、オペランドのサイズに応じて1つのオペランドがEAXまたはAXまたはALレジスタに格納されます。
  • BXは、インデックス付きアドレス指定で使用できるため、ベースレジスタとして知られています*。
  • CXは、カウントレジスタとして知られています。ECX、CXレジスタは、反復演算でループカウントを格納します。
  • DXはデータレジスタ*として知られています。 また、入出力操作でも使用されます。 また、大きな値を伴う乗算および除算演算のために、DXとともにAXレジスタとともに使用されます。

ポインタレジスタ

ポインタレジスタは、32ビットのEIP、ESP、およびEBPレジスタと、対応する16ビットの右部分IP、SP、およびBPです。 ポインタレジスタには3つのカテゴリがあります-

  • 命令ポインタ(IP)-16ビットIPレジスタには、次に実行される命令のオフセットアドレスが格納されます。 CSレジスタに関連付けられたIP(CS:IPとして)は、コードセグメント内の現在の命令の完全なアドレスを提供します。
  • スタックポインタ(SP)-16ビットSPレジスタは、プログラムスタック内のオフセット値を提供します。 SSレジスタに関連付けられたSP(SS:SP)は、プログラムスタック内のデータまたはアドレスの現在の位置を指します。
  • ベースポインター(BP)-16ビットBPレジスタは、主にサブルーチンに渡されるパラメーター変数の参照に役立ちます。 SSレジスタのアドレスをBPのオフセットと組み合わせて、パラメーターの位置を取得します。 BPは、特別なアドレッシング用のベースレジスタとしてDIおよびSIと組み合わせることができます。

ポインタレジスタ

インデックスレジスタ

32ビットのインデックスレジスタ、ESIおよびEDI、およびそれらの16ビットの右端部分。 SIおよびDIは、インデックス付きアドレス指定に使用され、加算および減算で使用されることもあります。 インデックスポインタの2つのセットがあります-

  • ソースインデックス(SI)-文字列操作のソースインデックスとして使用されます。
  • 宛先インデックス(DI)-文字列操作の宛先インデックスとして使用されます。

インデックスレジスタ

制御レジスタ

32ビット命令ポインタレジスタと32ビットフラグレジスタの組み合わせは、制御レジスタと見なされます。

多くの命令は比較と数学的計算を含み、フラグのステータスを変更し、他の条件付き命令はこれらのステータスフラグの値をテストして、制御フローを他の場所に移動します。

一般的なフラグビットは次のとおりです。

  • オーバーフローフラグ(OF)-符号付き算術演算後のデータの高位ビット(左端ビット)のオーバーフローを示します。
  • 方向フラグ(DF)-文字列データを移動または比較するための左または右の方向を決定します。 DF値が0の場合、文字列操作は左から右の方向になり、値が1に設定されている場合、文字列操作は右から左の方向になります。
  • 割り込みフラグ(IF)-キーボード入力などの外部割り込みを無視するか処理するかを決定します。 値が0の場合は外部割り込みを無効にし、1に設定されている場合は割り込みを有効にします。
  • トラップフラグ(TF)-シングルステップモードでプロセッサの動作を設定できます。 使用したDEBUGプログラムはトラップフラグを設定するため、一度に1命令ずつ実行を進めることができます。
  • * Sign Flag(SF)*-算術演算の結果の符号を示します。 このフラグは、算術演算に続くデータ項目の符号に従って設定されます。 符号は、左端ビットの上位で示されます。 正の結果はSFの値を0にクリアし、負の結果は1に設定します。
  • ゼロフラグ(ZF)-算術演算または比較演算の結果を示します。 ゼロ以外の結果はゼロフラグを0にクリアし、ゼロの結果は1に設定します。
  • 補助キャリーフラグ(AF)-算術演算後のビット3からビット4へのキャリーが含まれています。特殊な算術に使用されます。 AFは、1バイトの算術演算によりビット3からビット4へのキャリーが発生したときに設定されます。
  • パリティフラグ(PF)-算術演算から得られた結果の1ビットの総数を示します。 偶数の1ビットはパリティフラグを0にクリアし、奇数の1ビットはパリティフラグを1に設定します。
  • キャリーフラグ(CF)-算術演算後の上位ビット(左端)からの0または1のキャリーが含まれます。 また、_shift_または_rotate_操作の最後のビットの内容も保存します。

次の表は、16ビットフラグレジスタのフラグビットの位置を示しています。

Flag: O D I T S Z A P C
Bit no: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

セグメントレジスタ

セグメントは、データ、コード、およびスタックを含むためにプログラムで定義された特定の領域です。 3つの主要なセグメントがあります-

  • コードセグメント-実行されるすべての命令が含まれています。 16ビットコードセグメントレジスタまたはCSレジスタは、コードセグメントの開始アドレスを格納します。
  • データセグメント-データ、定数、および作業領域が含まれます。 16ビットのデータセグメントレジスタまたはDSレジスタは、データセグメントの開始アドレスを格納します。
  • スタックセグメント-プロシージャまたはサブルーチンのデータと戻りアドレスが含まれています。 「スタック」データ構造として実装されます。 スタックセグメントレジスタまたはSSレジスタには、スタックの開始アドレスが格納されます。

DS、CS、およびSSレジスタとは別に、データを格納するための追加のセグメントを提供する、ES(追加セグメント)、FS、およびGSの追加のセグメントレジスタがあります。

アセンブリプログラミングでは、プログラムはメモリの場所にアクセスする必要があります。 セグメント内のすべてのメモリ位置は、セグメントの開始アドレスに関連しています。 セグメントは、16または16進数で10で割り切れるアドレスで始まります。 したがって、このようなすべてのメモリアドレスの右端の16進数字は0であり、通常はセグメントレジスタに格納されません。

セグメントレジスタには、セグメントの開始アドレスが格納されます。 セグメント内のデータまたは命令の正確な位置を取得するには、オフセット値(または変位)が必要です。 セグメント内のメモリロケーションを参照するために、プロセッサは、セグメントレジスタ内のセグメントアドレスとロケーションのオフセット値を組み合わせます。

次の簡単なプログラムを見て、アセンブリプログラミングでのレジスタの使用を理解してください。 このプログラムは、簡単なメッセージとともに画面に9つの星を表示します-

section .text
   global _start     ;must be declared for linker (gcc)

_start:          ;tell linker entry point
   mov  edx,len  ;message length
   mov  ecx,msg  ;message to write
   mov  ebx,1    ;file descriptor (stdout)
   mov  eax,4    ;system call number (sys_write)
   int  0x80     ;call kernel

   mov  edx,9    ;message length
   mov  ecx,s2   ;message to write
   mov  ebx,1    ;file descriptor (stdout)
   mov  eax,4    ;system call number (sys_write)
   int  0x80     ;call kernel

   mov  eax,1    ;system call number (sys_exit)
   int  0x80     ;call kernel

section .data
msg db 'Displaying 9 stars',0xa ;a message
len equ $ - msg  ;length of message
s2 times 9 db '*'

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Displaying 9 stars
*********