intel-8086データシート
intel 8086のデータシートを読んでてちょくちょくと詰まった所があったので、それのメモ。
読んでた箇所は"Table2. Instruction Set Summary"で、MOV命令の箇所。どういうビット列がどの命令と解釈されるかと、特定の役割を持ったビットの説明について。
命令表
とりあえず、問題の命令表はこんな感じ
MOV命令
76543210 | 76543210 | 76543210 | 76543210 | |
Register/Memory to/from Register | 100010dw | mod reg r/m | ||
---|---|---|---|---|
Immediate to Register/memory | 1100011w | mod 000 r/m | data | data if w = 1 |
Immediate to Register | 1011 w reg | data | data if w = 1 | |
Memory to Accumulator | 1010000w | addr-low | addr-high | |
Accumulator to Memory | 1010001w | addr-low | addr-high | |
Register/Memory to Segment Register | 10001110 | mod 0 reg r/m | ||
Segment Register to Register/Memory | 10001100 | mod 0 reg r/m |
MOV命令はどういうビットで成り立っているかがこれよりわかる。なんか表が崩れたりするし、実際にどう書かれているかはデータシートそのものを見てもらった方がいい。
例えば"Register/Memory to/from Register"、つまりは、レジスタかメモリのどちらかからレジスタへの値のコピー。またはレジスタかメモリのどちらかへ、レジスタから値をコピーする命令は"100010"というビットで始まり、以降の10ビットによりメモリかレジスタかといったことや、レジスタならどのレジスタかという事を指定する。
ここで各命令の挙動を指定するビットである、"mod"や"r/m"やらの説明がデータシートの最終ページにあり、それらと合わせてビット列を読むことでどういう命令かが具体的にわかる。
動的ビットの説明
前述の各命令の挙動を示すビットについて、以下引用。
データシートからの引用
NOTES: AL = 8-bit accumulator AX = 16-bit accumulator CX = Count register DS = Data segment ES = Extra segment Above/below refers to unsigned value Greater = more positive; Less = less positive (more negative) signed values if d = 1 then ‘‘to’’ reg; if d e 0 then ‘‘from’’ reg if w = 1 then word instruction; if w e 0 then byte instruction if mod = 11 then r/m is treated as a REG field if mod = 00 then DISP = 0*, disp-low and disp-high are absent if mod = 01 then DISP = disp-low sign-extended to 16 bits, disp-high is absent if mod = 10 then DISP = disp-high; disp-low if r/m = 000 then EA = (BX) + (SI) + DISP if r/m = 001 then EA = (BX) + (DI) + DISP if r/m = 010 then EA = (BP) + (SI) + DISP if r/m = 011 then EA = (BP) + (DI) + DISP if r/m = 100 then EA = (SI) + DISP if r/m = 101 then EA = (DI) + DISP if r/m = 110 then EA = (BP) + DISP* if r/m = 111 then EA = (BX) + DISP DISP follows 2nd byte of instruction (before data if required) *except if mod = 00 and r/m = 110 then EA = disp-high; disp-low. if s w = 01 then 16 bits of immediate data form the operand if s w = 11 then an immediate data byte is sign extended to form the 16-bit operand if v e = then "count" = 1; if v = 1 then "count" in (CL) x = don’t care z is used for string primitives for comparison with ZF FLAG
略語
各要素は基本的に略語で書かれてるので、最初ちょっと途惑った。ということで、それらの説明。
略語 | 元の語 | 用法 |
---|---|---|
d | direction(多分) | レジスタへの操作か、レジスタからの操作かを示す |
w | word | データがword長か否かを示す |
mod | mode | 同命令内にあるdata部の扱いや、r/mの挙動を決める |
DISP | displacement | メモリの位置指定などに使用 |
r/m | register/memory(多分) | レジスタを使ってのメモリ指定パターン |
いくつか実例
MOV命令を読む際に使ったいくつかについて、実例を見てみる。
例1
16進数:b80100 2進数:10111000 00000001 00000000
の場合。先頭ビットから見ていくと、一致する命令は"Immediate to Register"であることがわかる。以降のビットを命令表のこの命令と照らし合わせてみると
w | 1 |
---|---|
reg | 000 |
data | 000000001 00000000 |
であることがわかる。regはレジスタを示すビット列で、これについてもデータシートの最終ページに対応表があるのでそちらを参照すると、wが1の場合、000はレジスタAXを示す。以上よりこの命令は
mov ax, 0x0001
となることがわかる。
例2
16進数:c7070200 2進数:11000111 00000111 00000010 00000000
の場合。同様に先頭ビットから見ていくと、一致する命令は"Immediate to Register/Memory"であることがわかる。以降のビットを命令表と照合してみると
w | 1 |
---|---|
mod | 00 |
r/m | 111 |
data | 00000010 00000000 |
であることがわかる。r/m=111の場合、"EA = (BP) + DISP"が当てはまる。また、mod=00の場合、DISPは0であるとして扱われるので、DISPを示す要素は存在しない。つまり"EA = (BP)"となり、dataはコピーされる即値に相当する。以上より
mov [bp], 0x0002
となることがわかる
例3
16進数:c78718010200 2真数:11000111 10000111 00011000 00000001 00000010 00000000
の場合。同様にしていくと、これもまた"Immediate to Register/Memory"である。命令決定以降のビットを照合していくと
w | 1 |
---|---|
mod | 10 |
r/m | 111 |
data | 00000010 00000000 |
w=1より、dataは末尾16ビットが相当するのだが、ここで丁度真ん中の16ビットが謎の存在になる。mod=01を見ると、"if mod = 10 then DISP = disp-high; disp-low"とあり、このDISPが9~32ビット目までに相当している。なぜここに差し込まれるかというと、"DISP follows 2nd byte of instruction (before data if required)"という説明にあるように、dataがあるならその前に入るようになっている。あとはr/m=111より"EA = (BX) + DISP"であることがわかる。以上より
mov [bx+0x118], 0x0002
となる
例4
16進数:c70600010a000 2進数:11000111 00000110 00000000 00000001 00001010 00000000
の場合、相変わらずこれも"Immediate to Register/Memory"である。以下同様にしていくと
w | 1 |
---|---|
mod | 00 |
r/m | 110 |
data | 00001010 00000000 |
例3と同様にしてdataは表の通りとわかる。mod=00なので"if mod = 00 then DISP = 0*, disp-low and disp-high are absent"に相当するかと思いきや、このアスタリスクが曲者。"*except if mod = 00 and r/m = 110 then EA = disp-high; disp-low."なんていう説明がありまして、mod=00かつr/m=110の場合は即値のコピー先が"EA = (BP) + DISP"から"EA = disp-high; disp-low"に変更となる。つまり、即値をDISPで指定されるメモリの位置にコピーしろという命令になる。よって以上より
mov [0x100], 0x000a
となる。
最後に
この8086のデータシートは"8086 datasheet"なんてググれば出てきますが、これって"mnemonic © intel, 1978"って、今更誰が使うんだレベルの古さですね。なんという誰得エントリ。