: .
, , , , , , .
NASM , , .
(8AC3) ( ), : addps 8A /r mov al, bl ModR/M addps . addps xmm0, xmm3 ModR/M (C3) mov al, bl, 8A /r.
, A (B) xmm0 (xmm0) .
, - , .
(re) , x86 .
, G P F (Group, oPeration, Flags).
G - , , , (, ).
.
P - ; , , - .
F - , . F , (, G = 2, P = 7 - mov r16, imm16, F r16).
mov, / , , G 2, P 1.
F - 3- :
2 1 0 bit
+---+---+---+
| s | d | b |
+---+---+---+
s = 1 if moving to/from a segment register
0 if moving to/from a gp register
d = 1 if moving mem -> reg
0 if moving mem <- reg
b = 1 if moving a WORD
0 if moving a BYTE
, .
G=2, P=1, F={s=0, d=0, b=0} 210 (88) mov r/m8, r8
G=2, P=1, F={s=0, d=0, b=1} 211 (89) mov r/m16, r16
G=2, P=1, F={s=0, d=1, b=0} 212 (8A) mov r8, r/m8
G=2, P=1, F={s=0, d=1, b=1} 213 (8B) mov r16, r/m16
G=2, P=1, F={s=1, d=0, b=0} 214 (8C) mov r/m16, Sreg
G=2, P=1, F={s=1, d=0, b=1} 215 (8D) Not a move, segment registers are 16-bit
G=2, P=1, F={s=1, d=1, b=0} 216 (8E) mov Sreg, r/m16
G=2, P=1, F={s=1, d=1, b=1} 217 (8F) Not a move, segment registers are 16-bit
ModR/M, .
ModR/M : X R M.
X M , .
R (, 0 = A, 3 = B).
(X = 3, M = ) ( M), .
, X = 3, R = 0, M = 3 (C3) B A .
X = 3, R = 3, M = 0 (D8) A B .
, : ModR/M . , - , .
, , B A.
A () B (), ModR/M X = 3, R = 0, M = 3 (C3).
B A, , 8 ,
G = 2, P = 1, F = {s = 0, d = 1, b = 0} (8A), mem- > reg (B- > A).
, - 8AC3.
A ( ) B (), ModR/M X = 3, R = 3, M = 0 (D8).
G = 2, P = 1, F = {s = 0, d = 0, b = 0} (88), reg- > mem (B- > A).
- 88D8.
If we want to move the entire 16-bit register (we ignore operand-size prefixes here), we simply set bit b from F:
G = 2, P = 1, F = {s = 0, d = 1, b = 1} for the first case, which leads to 8BC3.
G = 2, P = 1, F = {s = 0, d = 0, b = 1} for the second case, which leads to 89D8.
You can check it with ndisasm
00000000 8AC3 mov al,bl
00000002 88D8 mov al,bl
00000004 8BC3 mov ax,bx
00000006 89D8 mov ax,bx