8086 CPU 早わかり

  1. レジスタにデータを書く.
    ニーモニック 機械語 意味
    mov al,XY B0,XY al = XY
    mov bl,XY B3,XY bl = XY
    mov dl,XY B2,XY dl = XY
    mov ah,XY B4,XY ah = XY
    mov bh,XY B7,XY bh = XY
    mov dh,XY B6,XY dh = XY
    mov ax,XYPQ B8,PQ, XY ax = XYPQ
    mov bx,XYPQ BB,PQ, XY bx = XYPQ
  2. レジスタ間のデータ移動.
    ニーモニック 機械語 意味
    mov bl,al 88,c3 bl = al
    mov dl,al 88,c2 dl = al
    mov al,bl 88,d8 al = bl
    mov al,dl 88,d0 al = dl
    mov ds,ax 8e,d8 ds = ax
  3. メモリへのデータの書き込み
    ニーモニック 機械語 意味
    mov [bx],al 88,07 *bx = al
  4. ++
    ニーモニック 機械語 意味
    inc bx 43 bx++
  5. 比較, 分岐
    ニーモニック 機械語 意味
    cmp bx,XYPQ 81,fb,PQ,XY bx!=XYPQ ?
    JNZ ???? 0f,85,PQ,XY ip += XYPQ
    JNZ ?? 75,XY ip += XY
    int 20 cd,20 DOS へ戻る.
    int 21 cd,21 DOS システムコール
  6. 計算
    ニーモニック 機械語 意味
    add al,XY 04,XY al += XY
    add al,bl 00,d8 al += bl
    shl al,1 d0,e0 al << 1
    shl al,2 c0,e0,02 al << 2
    shl al,3 c0,e0,03 al << 3
  7. Stack 操作
    ニーモニック 機械語 意味
    push ax 50 ax を stack に push
    pop ax 58 stack から pop して ax に代入
    push bx 53 bx を stack に push
    pop bx 5B stack から pop して bx に代入
例 A. al に 2 を代入してそれを5倍して al に格納するプログラム(足し算でやる)
b0,02
88,c3
00,d8
00,d8
00,d8
00,d8
練習 1: shl を利用して 5 倍せよ.

練習 2(大事): メモリ番地 b800:0000 から b800:0100 に 41H を書き込むプログラム. ヒント: ds レジスタに b800 を代入. bx を 0000 から 0100 まで変化させながら mov [bx],al を用いる. C言語のポインター(アドレスを入れる変数)の正体.
解説: x:y なるメモリ番地の記法は x*0x10+y の略. たとえば b800:0100 は b8100 を意味する. この記法は 8086 CPU の仕組みに基づいた記法. mov [bx],al は ds:bx 番地への書き込みとなる. たとえば ds に b800, bx に 0100 が格納されている場合, b8100 番地へ al の内容を書き込む.



例 B: al=2 を2倍してそれを MSDOS システムコール で '0' のアスキーコードに足して出力.
b0,02   mov al,02
d0,e0   shl al,1
04,30   add al,30
88,c2   mov dl,al
b4,02   mov ah,02
cd,21   int 21
cd,20   int 20

練習 3: C 言語で上記例Bのマシン語が格納されたファイル bbb.com を作成して dosbox-x で実行. FreeDOS の usb boot を用いて実機でも実行.
練習3の解答 (bbb.com の作り方)

練習 4: C 言語で練習2のマシン語が格納されたファイル abc.com を作成して dosbox-x で実行. 最後に int 20 の追加を忘れずに. FreeDOS の usb boot を用いて実機でも実行.

練習 5: 例A, 練習 1 のプログラムを linux の a.out に hexcurse で埋め込みその a.out を実行. 3 を5倍, 4 を5倍などいろんな数で試す.
実演: youtube
実演でも用いた nop (0x90) で 32 byte分埋めてある a.out ファイルは こちら (名前は myasm-m3.out) . eax レジスタの内容が printf で10進数表示される.
myasm-m3.out みたいなファイルを自作するヒント: cc -S でマシン語のニーモニックファイルを出力. 空欄のある a.out を作成.



8086 機械語学習用参考リンク

  1. mathlibre-2019 を利用している場合は, dosbox & と入力すれば 上記練習問題が実行可能. キーボードは下記の us 101 キーボード. たとえば mathlibre-2019 の /home/user/DOS を dosbox から読み書きするには (mkdir ~/DOS を mathlibre 側で実行してこのフォルダを作成し) dosbox へ下記を入力.
    mount c /home/user/DOS
    cd c:
    
    たとえば /home/user/DOS/a.com を実行するには, 上記を実行したあと
    dir   (ファイル一覧で a.com があるか確認)
    a     (a.com の実行)
    
    と入力.
    hexcurse のインストールは
    sudo apt update
    sudo apt install hexcurse
    
  2. DOSBox-x (MSDOS 仮想マシン)の配布サイト. dosbox-x は dosbox より高機能.
    Default sdl2.build, copy all DOSBox-X にチェックを入れてインストール.
    Mac では ctrl+click で security 制限を外して起動.
  3. はじめて読む8086 (internet archive).
  4. 8086 の命令はたとえば 64 bit linux のマシン語コードにも埋め込めます. hexcurse で機械語をそのまま埋め込んでみて下さい. ニーモニックならたとえば %al が AL レジスタのこと.


参考メモ

  1. chev us (us mode in dosvaxj3 on windows). DOSBox-X では最初から us mode.
  2. mount c c:\Users\takay\DOS (on dosvaxj3)
  3. b800:0000 (character vram in us mode)
  4. a000:7f00 (video vram, by switching the mode by "mov ax,62; int 10; int 20")
  5. *-com.txt (input for debug), DOS/*COM , myasm*
  6. ah=02 dl=ascii code int 21 で文字出力.
  7. ah=07 al=key code int 21 で直接コンソール入力
  8. 90, nop の代わり.

dosbox では int20 を使わない

int 20 の代わりに
mov ah,4c
int 21
  1. 詳しい記事 at stackoverflow .
  2. int 21 の機能一覧 .
  3. アセンブラを理解したいのならアセンブラを学べ(INT 21Hもあるよ).