4

I'm writing an assembler. I always thought that assembly had a 1:1 correspondence between a certain assembly instruction and corresponding instruction, so I thought it would be fairly easy to write one. But after actually reading the Intel 64 Software Dev Manual, I now realize that a command like

mov %rdx,%rbx

has a certain ambivalence to it. It could be translated to 48 89 D3 which corresponds to

REX.W + 89 /r - MOV r64,r/m64

from page 1235 of the Intel 64 Software Dev Manual.

But it could also be translated to 48 8B DA (REX.W + 8B /r - MOV r/m64,r64).

This is the output from a disassembly by objdump -d of the binary:

0:  48 89 d3                mov    %rdx,%rbx
3:  48 8b da                mov    %rdx,%rbx

By reading the manual it is pretty obvious why this ambivalence exists. There are a handful of cases where there is ambivalence like this.

I have tested the code in some instances and it performed exactly the same.

Is there a benefit of using the one over the other (gnu assembler uses 48 89 D3 in all cases I looked at) or should I just pick one of them at random?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 3
    There is no advantage per se, but under certain circumstances the programmer cares about the encoding. For such cases some assemblers support choosing the other one. E.g. gnu assembler has a `mov.s %rdx, %rbx`. Also, why are you writing yet another assembler :) – Jester May 03 '21 at 11:27
  • 2
    "at random" - some assemblers have used this choice to "watermark" machine code, so people could tell code was produced by that assembler. (Specifically some commercial shareware assembler, so the author could tell if someone without a license was distributing binaries assembled with it.) – Peter Cordes May 03 '21 at 12:21
  • 2
    BTW, "redundancy" is probably a better word than "ambivalence". "Ambivalence" means "indifference", with connotations of a *person* not caring about what choice something *else* makes, not usually used to describe the fact that an equal choice exists. – Peter Cordes May 03 '21 at 12:24
  • 1
    Re: performance: AFAIK there aren't any cases where the `r, r/m` encoding decodes or executes more or less efficiently on any existing microarchitectures than the `r/m, r` encoding, for reg,reg instructions. https://uops.info/ does test both encodings for instructions that can be encoded more than one way. – Peter Cordes May 03 '21 at 12:29
  • 2
    Alternative encoding may lead to a different code size, see https://euroassembler.eu/eadoc/#CODEeq, so there can be a benefit in instruction size. – vitsoft May 03 '21 at 12:38
  • 2
    @vitsoft: Oh yes, I though the question was specific to the r/m source vs. destination choice (where it never makes a size difference). Yes, special-case encodings to save space ([Tips for golfing in x86/x64 machine code](https://codegolf.stackexchange.com/a/160739)) are usually good and thus can improve speed indirectly via I-cache, decode, and uop-cache packing effects. There's one case where it's actually slower, though: `adc al, 0` is 2 uops even on Skylake, and defeats [Which Intel microarchitecture introduced the ADC reg,0 single-uop special case?](https://stackoverflow.com/q/51664369) – Peter Cordes May 03 '21 at 13:53
  • 2
    @vitsoft: we have some other existing Q&As about other choices between opcodes, e.g. [x86 instruction encoding how to choose opcode](https://stackoverflow.com/q/37611247) - adding those to the duplicate list. And for good measure, another perf-affecting case about `[rax + rax + 1]` vs. `[1 + rax*2]` which affects LEA latency. – Peter Cordes May 03 '21 at 13:54
  • 2
    Also related: [Why NASM on Linux changes registers in x86\_64 assembly](https://stackoverflow.com/q/48596247) - some assemblers will save beginners from themselves and optimize `xor rax,rax` into `xor eax,eax` for example. (And a good example of NASM `mov rax, strict qword 123` to force the imm64 encoding; occasionally useful to be able to force longer / specific encodings. Also `{vex3}` vs. using 2-byte VEX when possible for AVX instructions.) – Peter Cordes May 03 '21 at 13:58

0 Answers0