The difference between MOV r / m8, r8 and MOV r8, r / m8

Looking at the scope of the intel instructions, I found the following:

1) 88 /r MOV r/m8,r8
2)8A /r MOV r8,r/m8

When I write this line in NASM and compile it with the listing option:

mov al, bl

I get this in the list:

88D8 mov al, bl

So, NASM chose the first instruction from the two above, but is the second option not the second instruction? if so, on what basis did NASM choose the first?

+4
source share
3 answers

, modr/m . , mov r8,m8, mov m8,r8, . , mov, , , nasm . , , .

, , , . , , , .

+3

: A86.

  1. A86 , . (, MOV AX, BX 89 8B, . .) A86 . "", , , , , A86. "" , . "footprint", , - . :

    . , "", .    ,    , ,    .

    . , "footprint"    . 5 .

+6

: .
, , , , , , .

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
+3
source

Source: https://habr.com/ru/post/1678439/


All Articles