Opecode MOV - HobbyOSs/opennask GitHub Wiki

mod=00: [レジスター + レジスター]
mod=01: [レジスター + disp8]
mod=10: [レジスター + disp16/32]
mod=11: レジスター
今回はすべて
☆ 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

MOV命令(imm→r)

"+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に転送します