7

When assembling this code with nasm:

BITS 64
mov eax, 0x1
mov rax, 0x1

I get this output:

b8 01 00 00 00 b8 01 00 00 00

which is the opcode for mov eax, 0x1 repeated twice.

Does this mean that mov rax, 0x1 can always be replaced by mov eax, 0x1 or is it just in this case?

If this is correct wouldn't it be better to use than:

xor rax, rax
inc rax

as that becomes 6 bytes when assembled while mov eax, 0x1 is only 5 bytes?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Tyilo
  • 28,998
  • 40
  • 113
  • 198
  • 1
    Relevant: http://stackoverflow.com/questions/8502839/loading-small-numbers-into-64-bit-x86-registers – Jens Björnhager Aug 06 '12 at 05:54
  • 4
    Actually, because the first snippet is correct, the second snippet would only take 4 bytes (no REX prefixes required). – harold Aug 06 '12 at 08:42
  • 1
    `xor eax,eax` / `inc eax` is 4B, slightly smaller than `mov eax, 1`. But don't use that unless you're heavily optimizing for code-size. Spending 1 byte to save an instruction (and a fused-domain uop) is worth it for modern CPUs. – Peter Cordes May 20 '16 at 06:33
  • you can use [`mov rax, strict dword/qword 1` to force the 7/10-byte version of mov](https://stackoverflow.com/a/48597025/995714) – phuclv Jul 24 '18 at 10:45

1 Answers1

8

Always. Most (if not all) 32-bit MOVs and ALU operations clear bits 32 through 63 of the destination register operand. See the CPU manual for details.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180