この記事では、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に移動します。