MOV rA, rB: B: AL AH BL BH CL CH DL DH A: 1 1 0 0 1 1 0 0 AL 1 ** ** 8A 8A ** ** 8A 8A AH 1 ** ** 8A 8A ** ** 8A 8A BL 0 8A 8A ** ** 8A 8A ** ** BH 0 8A 8A ** ** 8A 8A ** ** CL 1 ** ** 8A 8A ** ** 8A 8A CH 1 ** ** 8A 8A ** ** 8A 8A DL 0 8A 8A ** ** 8A 8A ** ** DH 0 8A 8A ** ** 8A 8A ** ** * = "reversed" opcode (88) MOV rA, rB ( word regs ): B: AX BX CX DX SP BP SI DI A: 1 0 1 0 1 1 0 0 AX 1 ** 8B ** 8B ** ** 8B 8B BX 0 8B ** 8B ** 8B 8B ** ** CX 1 ** 8B ** 8B ** ** 8B 8B DX 0 8B ** 8B ** 8B 8B ** ** SP 1 ** 8B ** 8B ** ** 8B 8B BP 1 ** 8B ** 8B ** ** 8B 8B SI 0 8B ** 8B ** 8B 8B ** ** DI 0 8B ** 8B ** 8B 8B ** ** * = "reversed" opcode (89) The above tables apply for the following two-operand instructions: ADD OR ADC SBB AND SUB XOR CMP For TEST and XCHG, which are commutative, A86 always puts the first operand in the r/m field if possible, while MASM puts it in the reg field if the first operand is a register.
I would never have imagined that I'd get an answer to that question a quarter of a century later. Thanks for the comment!