ぐだぐだ低レベルプログラミング(201)x86(16bit)、ポインタロード、LES、LDS

Joseph Halfmoon

前回は8086範囲をはみ出すENTER/LEAVE命令でしたが、今回は8086以来のファーポインタ(セグメント間参照)のロード命令、LESとLDSです。そろそろ8086命令は一巡するんじゃないかなどと思っていたのですが、数えてみたらまだまだ残ってます。先が長いのでそろそろ8086範囲は終わらせたいのだけれど。

※「ぐだぐだ低レベル プログラミング」投稿順indexはこちら

※実機動作確認(といってもエミュレータなんだけれども)には以下を使用させていただいております。

    •  Windows 11 PC (i5-1235U)
    •  Ubuntu 24.04 LTS on WSL2
    •  QEMU 8.2.2
    •  FreeDOS 1.3
ファー・ポインタのロード命令、LESとLDS

8086以来の16ビットx86の場合、マジメにセグメントと向き合わないとならないので、メモリを指すポインタにもセグメント内のオフセットアドレスだけを使うケース(ニア)と、セグメント値とオフセットを組で使うケース(ファー)を使いわけないとなりませぬ。

そのうち、「組」での操作を強いられるファーポインタの場合、セグメント・レジスタへのロードと、ベース・レジスタへのロードを2回にわけるのもなんだかな~ということで以下の2命令が用意されとります。

    • LDS、DSセグメントレジスタとベースレジスタの2本に値をロード
    • LES、ESセグメントレジスタとベースレジスタの2本に値をロード

ここではオフセットアドレスをロードしてアドレシングに使われるのであろうレジスタをベースと表現しています。マニュアル的にはいろいろありーの。オペコードマップ的には以下です。LES_LDS_opcode

8086的にはセグメント・レジスタは4本ありますが、ES、DSのみ対象です。残りの2本に対しては用意されてません。コードセグメントCSにロードしてしまうとJMPになってしまうのでデータ・ポインタのロードとは違うし。またスタックセグメントSSは、「ころころ変えるものでもない」(スタックフレームとか割り込みとかあるもんね、変えるときは関係各位の整合性をとらないと)ということなのでしょう。知らんけど。

今回実験のプログラム

強力なx86用アセンブラNASM用のソースです。ファーポインタをロードしてみるのにデータ・セグメントを複数定義してます(ポインタロードだけで使うわけでもないんだけれども。)ブロック転送命令の準備でも使える?雰囲気を醸すためにES:DI、とDS:SIを組にしてロードしています。

segment code

..start:
    mov ax, data0
    mov ds, ax
    mov es, ax
    mov ax, stack
    mov ss, ax
    mov sp, stacktop
test:
    mov bx, espointer
    les di, [bx]
    add bx, 4
    lds si, [bx]
fin:
    mov ax, 0x4c00
    int 0x21
    resb    2048

segment data0   align=16
    resb    1024 * 63
espointer:
    dw    estarget
    dw    data1
dspointer:
    dw    dstarget
    dw    data2

segment data1   align=16
    resb    1024 * 63
estarget:
    dw    0

segment data2   align=16
    resb    1024 * 63
dstarget:
    dw    0

segment stack   class=STACK align=16
    resb    2048
stacktop:
    dw 1024 dup (0)
stackend:
アセンブルして実行

MS-DOS互換で機能強化されてるフリーなFreeDOS上、以下のステップで上記のアセンブラソース leslds.asm から実行可能なオブジェクトファイルを生成して実行することができます(nasmとwatcom Cがインストール済であること。)今回からアセンブル時にリスティング・ファイルも生成されるように -l オプションを使うことにいたしました。

nasm -f obj -l leslds.lst leslds.asm 
wlink name leslds.exe format dos file leslds.obj
debug leslds.exe

今回実行プログラムはごく短いので、デバッガ上で一画面の逆アセンブルで足ります。LES_LDS_u

オフセット0x000F番地以降がテスト本体です。以下のトレース履歴で、赤枠をつけてあるのが、LES命令と関係レジスタの前後の値です。また、緑枠をつけてあるのが、LDS命令と関係レジスタの前後の値です。なお、メモリ参照のDS:~のところが両方緑枠になっているのは誤りで上の方は赤枠です。すみません。LES_LDS_pointerload

まあ、赤枠のLES命令で、ES:DIの2レジスタが1命令でロードされており、緑枠のLDS命令で、DS:SIの2レジスタが1命令でロードされていることが分かると思います。こんだけ。

ぐだぐだ低レベルプログラミング(200)x86(16bit)、ENTER、LEAVEその2 へ戻る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です