Assembly-programming-assembly-addressing-modes

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

アセンブリ-アドレス指定モード

ほとんどのアセンブリ言語命令では、オペランドを処理する必要があります。 オペランドアドレスは、処理されるデータが保存される場所を提供します。 オペランドを必要としない命令もあれば、1つ、2つ、または3つのオペランドを必要とする命令もあります。

命令に2つのオペランドが必要な場合、通常、最初のオペランドはデスティネーションであり、レジスタまたはメモリの場所にデータが含まれ、2番目のオペランドはソースです。 ソースには、配信されるデータ(即時アドレス指定)またはデータのアドレス(レジスタまたはメモリ内)が含まれます。 通常、ソースデータは操作後も変更されません。

アドレッシングの3つの基本モードは次のとおりです-

  • レジスタのアドレス指定
  • 即時アドレス指定
  • メモリアドレッシング

レジスタのアドレス指定

このアドレッシングモードでは、レジスタにオペランドが含まれています。 命令に応じて、レジスタは第1オペランド、第2オペランド、またはその両方になります。

例えば、

MOV DX, TAX_RATE   ; Register in first operand
MOV COUNT, CX      ; Register in second operand
MOV EAX, EBX       ; Both the operands are in registers

レジスタ間のデータ処理にはメモリが関与しないため、データの処理が最速になります。

即時アドレス指定

即値オペランドには、定数値または式があります。 2つのオペランドを持つ命令が即時アドレス指定を使用する場合、最初のオペランドはレジスタまたはメモリの場所であり、2番目のオペランドは即時定数です。 最初のオペランドは、データの長さを定義します。

例えば、

BYTE_VALUE  DB  150    ; A byte value is defined
WORD_VALUE  DW  300    ; A word value is defined
ADD  BYTE_VALUE, 65    ; An immediate operand 65 is added
MOV  AX, 45H           ; Immediate constant 45H is transferred to AX

ダイレクトメモリアドレッシング

オペランドがメモリアドレッシングモードで指定されている場合、通常はデータセグメントへのメインメモリへの直接アクセスが必要です。 このアドレス指定方法では、データの処理が遅くなります。 メモリ内のデータの正確な位置を特定するには、通常DSレジスタとオフセット値にあるセグメント開始アドレスが必要です。 このオフセット値は、*有効アドレス*とも呼ばれます。

直接アドレス指定モードでは、オフセット値は通常、変数名で示される命令の一部として直接指定されます。 アセンブラは、オフセット値を計算し、プログラムで使用されるすべての変数のオフセット値を格納するシンボルテーブルを維持します。

ダイレクトメモリアドレッシングでは、オペランドの1つがメモリ位置を参照し、他のオペランドがレジスタを参照します。

例えば、

ADD BYTE_VALUE, DL  ; Adds the register in the memory location
MOV BX, WORD_VALUE  ; Operand from the memory is added to register

直接オフセットアドレッシング

このアドレス指定モードでは、算術演算子を使用してアドレスを変更します。 たとえば、データのテーブルを定義する次の定義を見てください-

BYTE_TABLE DB  14, 15, 22, 45      ; Tables of bytes
WORD_TABLE DW  134, 345, 564, 123  ; Tables of words

次の操作は、メモリ内のテーブルからレジスタにデータにアクセスします-

MOV CL, BYTE_TABLE[2]   ; Gets the 3rd element of the BYTE_TABLE
MOV CL, BYTE_TABLE + 2  ; Gets the 3rd element of the BYTE_TABLE
MOV CX, WORD_TABLE[3]   ; Gets the 4th element of the WORD_TABLE
MOV CX, WORD_TABLE + 3  ; Gets the 4th element of the WORD_TABLE

間接メモリアドレス指定

このアドレス指定モードは、コンピューターの_Segment:Offset_アドレス指定機能を利用します。 一般に、メモリ参照用の角括弧内にコード化されたベースレジスタEBX、EBP(またはBX、BP)およびインデックスレジスタ(DI、SI)がこの目的に使用されます。

間接アドレス指定は通常、配列などのいくつかの要素を含む変数に使用されます。 アレイの開始アドレスは、たとえばEBXレジスタに保存されます。

次のコードスニペットは、変数のさまざまな要素にアクセスする方法を示しています。

MY_TABLE TIMES 10 DW 0  ; Allocates 10 words (2 bytes) each initialized to 0
MOV EBX, [MY_TABLE]     ; Effective Address of MY_TABLE in EBX
MOV [EBX], 110          ; MY_TABLE[0] = 110
ADD EBX, 2              ; EBX = EBX +2
MOV [EBX], 123          ; MY_TABLE[1] = 123

MOV命令

あるストレージスペースから別のストレージスペースにデータを移動するために使用されるMOV命令をすでに使用しています。 MOV命令は2つのオペランドを取ります。

構文

MOV命令の構文は-

MOV  destination, source

MOV命令は、次の5つの形式のいずれかを持つことができます-

MOV  register, register
MOV  register, immediate
MOV  memory, immediate
MOV  register, memory
MOV  memory, register

次のことに注意してください-

  • MOV操作のオペランドは両方とも同じサイズでなければなりません
  • ソースオペランドの値は変更されません

MOV命令は、あいまいさを引き起こすことがあります。 たとえば、ステートメントを見てください-

MOV  EBX, [MY_TABLE]  ; Effective Address of MY_TABLE in EBX
MOV  [EBX], 110       ; MY_TABLE[0] = 110

110に相当するバイトを移動するのか、ワードに相当するのを移動するのかは明確ではありません。 そのような場合、 type specifier を使用するのが賢明です。

次の表は、一般的な型指定子の一部を示しています-

Type Specifier Bytes addressed
BYTE 1
WORD 2
DWORD 4
QWORD 8
TBYTE 10

次のプログラムは、上記で説明した概念の一部を示しています。 メモリのデータセクションに「Zara Ali」という名前を保存し、プログラムで値を別の名前「Nuha Ali」に変更し、両方の名前を表示します。

section .text
   global_start     ;must be declared for linker (ld)
_start:             ;tell linker entry point

   ;writing the name 'Zara Ali'
   mov  edx,9       ;message length
   mov  ecx, name   ;message to write
   mov  ebx,1       ;file descriptor (stdout)
   mov  eax,4       ;system call number (sys_write)
   int  0x80        ;call kernel

   mov  [name],  dword 'Nuha'    ; Changed the name to Nuha Ali

   ;writing the name 'Nuha Ali'
   mov  edx,8       ;message length
   mov  ecx,name    ;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
name db 'Zara Ali '

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

Zara Ali Nuha Ali