8086 CPU 早わかり
- XY や PQ は 16進表示の数.
- ax,bx,cx,dx,ds は 16bit (16進4桁) レジスター.
- al は ax の下8bit. bl は bx の下8bit. cx,dx も同様のネーミング.
- ah は ax の上8bit. bh は bx の上8bit. cx,dx も同様のネーミング.
- ip (16bit) は instruction pointer (実行してる命令の次のアドレスが入ってる)
後ろへ戻る時は 2 の補数表現を用いる.
- 以下, 大文字、小文字は区別しません(気分で大文字になってたり小文字になってたりします).
- レジスタにデータを書く.
ニーモニック | 機械語 | 意味 |
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 |
- レジスタ間のデータ移動.
ニーモニック | 機械語 | 意味 |
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 |
- メモリへのデータの書き込み
ニーモニック | 機械語 | 意味 |
mov [bx],al | 88,07 | *bx = al |
- ++
ニーモニック | 機械語 | 意味 |
inc bx | 43 | bx++ |
- 比較, 分岐
ニーモニック | 機械語 | 意味 |
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 システムコール |
- 計算
ニーモニック | 機械語 | 意味 |
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 |
- 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 機械語学習用参考リンク
- 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
- DOSBox-x (MSDOS 仮想マシン)の配布サイト.
dosbox-x は dosbox より高機能.
Default sdl2.build,
copy all DOSBox-X にチェックを入れてインストール.
Mac では ctrl+click で security 制限を外して起動.
-
はじめて読む8086 (internet archive).
- 8086 の命令はたとえば 64 bit linux のマシン語コードにも埋め込めます.
hexcurse で機械語をそのまま埋め込んでみて下さい.
ニーモニックならたとえば %al が AL レジスタのこと.
参考メモ
- chev us (us mode in dosvaxj3 on windows). DOSBox-X では最初から us mode.
- mount c c:\Users\takay\DOS (on dosvaxj3)
- b800:0000 (character vram in us mode)
- a000:7f00 (video vram, by switching the mode by "mov ax,62; int 10; int 20")
- *-com.txt (input for debug), DOS/*COM , myasm*
- ah=02 dl=ascii code int 21 で文字出力.
- ah=07 al=key code int 21 で直接コンソール入力
- 90, nop の代わり.
dosbox では int20 を使わない
int 20 の代わりに
mov ah,4c
int 21
-
詳しい記事 at stackoverflow .
- int 21 の機能一覧 .
-
アセンブラを理解したいのならアセンブラを学べ(INT 21Hもあるよ).