X86アーキテクチャの命令基礎: BXとLOOP命令

この記事では、X86アーキテクチャにおける基本的な命令について説明します。

記述記号: "()"

記述上の簡潔さのために、"( )"を使用してレジスタやメモリーセルの内容を表します。

  • (ax)はaxレジスタの内容を表し、(al)はalレジスタの内容を表します。
  • (20000H)は物理アドレス20000Hにあるメモリーセルの内容を表します。
  • ((ds)*16+(bx))はdsレジスタの内容をADR1、bxレジスタの内容をADR2とすると、メモリーセルADR1*16+ADR2の内容を表します。

"()"内の要素は3種類あります: レジスタ名、セグメントレジスタ名、物理アドレス(20ビットデータ)。

IDATA定数

Debugで使ったような命令mov ax,[0]は、ds:0にあるデータをaxに移動します。"[ ]"内には通常、オフセットアドレスを表す定数が使用されます。これを**idata**と呼びます。

[BX]

mov ax,[bx]

  • bxレジスタの内容がオフセットアドレス(EA)となり、セグメントアドレス(SA)はデフォルトでdsとなります。SA:EAにあるデータをaxに移動します。

mov [bx],ax

  • bxレジスタの内容がオフセットアドレス(EA)となり、セグメントアドレス(SA)はデフォルトでdsとなります。axのデータをメモリーセルSA:EAに移動します。

LOOP

LOOP命令の形式はloop ラベルです。

  • (cx)=(cx)-1;
  • (cx)がゼロでない場合はラベルの位置に戻ってプログラムを実行し、ゼロであれば次の命令を実行します。

cxレジスタにループ回数を設定し、LOOP命令を使ってループを制御できます。

mov cx,11
s: add ax,ax
   loop s

DebugとMASMでの命令の異なる処理

例えば、mov ax,[0]という命令はDebugではds:0にあるデータをaxに移動しますが、MASMでは定数0をaxに移動するように解釈されます。

メモリーセル2000:0から2000:3のデータをal,bl,cl,dlに移動させる方法を比較します。

; Debugでのコード
mov ax,2000
mov ds,ax 
mov al, [0]
mov bl, [1]
mov cl, [2]
mov dl, [3]
; MASMでのコード
assume cs:code 
code segment

mov ax,2000h 
mov ds,ax 
mov al, ds:[0]
mov bl, ds:[1]
mov cl, ds:[2]
mov dl, ds:[3]

mov ax,4c00h
int 21h

code ends 
end

LOOPと[BX]の組み合わせ

ffff:0からffff:bまでのデータの合計値を計算し、結果をdxに格納します。

assume cs:code
code segment

	mov ax,ffffh
	mov ds,ax
	mov bx,0		;ds:bxをffff:0に初期化
	mov dx,0		;累積レジスタdxを初期化
	mov cx,12		;ループカウンタcxを初期化

s:  mov al, [bx]
	mov ah,0
	add dx,ax		;dxに((ds) *16+ (bx) )の値を加算
	inc bx			;ds:bxを次のセルに変更
	loop s

	mov ax,4c00h
	int 21h

code ends 
end

セグメントプレフィックス

mov ax,[bx]の例では、オフセットアドレスはbxから取得され、セグメントアドレスはデフォルトでdsとなります。しかし、セグメントアドレスを明示的に指定することも可能です。

mov ax,ds:[bx]

これは、bxからオフセットアドレスを取り、セグメントアドレスをdsから取り、そのメモリーセルの内容をaxに移動します。

タグ: x86 アセンブリ言語 LOOP命令 BXレジスタ

6月16日 22:30 投稿