Opecode MOV - HobbyOSs/opennask GitHub Wiki
-
ModR/Mバイトの解釈
- 概要説明: ModR/M
-
modは、次のようにr/mの用途を切り替える。
- ざっくり説明;実際にはもう少し複雑
- Intelの本, p.35, 36あたりに記載がある: IA-32 インテル ® アーキテクチャ ソフトウェア・デベロッパーズ・ マニュアル 中巻 A:命令セット・リファレンス A-M
mod=00: [レジスター + レジスター]
mod=01: [レジスター + disp8]
mod=10: [レジスター + disp16/32]
mod=11: レジスター
- ModR/Mバイトの解釈のしかた
- 2進数、8進数、10進数、16進数相互変換ツール
[xx,xxx,xxx] -> mod,reg&opecode,r/m
今回はすべて
☆ mod=11: レジスター指定
☆ r/m=000: AL/AX/EAXを指定されたとCPUに解釈させる
☆ opecode: 以下のように定められているらしい(誰が決めた?)
sss : Segment Register
000 : ES
001 : CS
010 : SS
011 : DS
100 : FS (Only 386+)
101 : GS (Only 386+)
rrr : W=0 : W=1 : reg32
000 : AL : AX : EAX
001 : CL : CX : ECX
010 : DL : DX : EDX
011 : BL : BX : EBX
100 : AH : SP : ESP
101 : CH : BP : EBP
110 : DH : SI : ESI
111 : BH : DI : EDI
; MOV SS,AX
; [d0 = 11/010/000] ... 010 =>
d08e
; MOV CS,AX
; [c8 = 11/001/000] ... 001 =>
c88e
; MOV DS,AX
; [d8 = 11/011/000] ... 011 =>
d88e
; MOV ES,AX
; [c0 = 11/000/000] ... 000 =>
c08e
; MOV SP,0x7c00 ; d0bc 007c
; c4, cc, dc, ec, fc
; [?? = 11/xxx/100]
; MOV SP,0x7c00
; MOV Reg,Imm
; 1011wrrr
- +rb、+rw,+rd
"+rb、+rw,+rdとありますが、これは、転送先レジスタに応じて、オペコードに以下の値を加算した値が、
実際のオペコードになることを意味します。例えば、EBXレジスタに対するMOV命令は、0xB8+3=「0xBB」になります。"
rb rw rd
AL = 0 AX = 0 EAX = 0
CL = 1 CX = 1 ECX = 1
DL = 2 DX = 2 EDX = 2
BL = 3 BX = 3 EBX = 3
AH = 4 SP = 4 ESP = 4
CH = 5 BP = 5 EBP = 5
DH = 6 SI = 6 ESI = 6
BH = 7 DI = 7 EDI = 7
- MOVではlabelは即値として扱われる
特殊に見えるが0xB8+rw | MOV r16, imm16
の機械語にあたる
; 0xbe : 0xB8+r, SIは+6(110)なので0xB8+6=0xBE
; 0x74,0x7c: このMOV命令からラベルまでの距離をWORD単位で格納(リトルエンディアン)なのだが、0x74は全体のバイト数の累積となる
MOV SI,msg ; be747c
- MOV(Move to/from Control Registers)命令
なんか特殊な命令を実行するのに必要
0x0F 0x22 /r MOV CR0, r32 r32をCR0に転送します
0x0F 0x22 /r MOV CR2, r32 r32をCR2に転送します
0x0F 0x22 /r MOV CR3, r32 r32をCR3に転送します
0x0F 0x22 /r MOV CR4, r32 r32をCR4に転送します
0x0F 0x20 /r MOV r32, CR0 CR0をr32に転送します
0x0F 0x20 /r MOV r32, CR2 CR2をr32に転送します
0x0F 0x20 /r MOV r32, CR3 CR3をr32に転送します
0x0F 0x20 /r MOV r32, CR4 CR4をr32に転送します