1

The popular method to clear rax is xor rax,rax (0x4831C0) but that operation affects the flag bits.

How to clear rax without affecting the flags?

For example:

mov rax,0 (0x48C7C0xxxxxxxx takes 7 bytes)
pushf + xor rax,rax + popf (0x9C31C09D takes 4 bytes).
push 0 + pop rax (0x6A0058 takes 3 bytes)

Are there more or better methods?

phuclv
  • 37,963
  • 15
  • 156
  • 475
user2707695
  • 126
  • 1
  • 12
  • 4
    No, the popular method is `xor eax,eax`. The instruction `xor rax,rax` is encoded as `48 31 c0` which wastes an extra byte. – fuz May 07 '18 at 21:25
  • 5
    If you really need to clear a register such that the flags are unaffected (typically an undesired feature), `mov eax,0` is the way to go. – fuz May 07 '18 at 21:27
  • 2
    Just to clarify what fuz is saying: Using `mov eax,0` really does clear all 64 bits of rax, and is (slightly) smaller than `mov rax,0` (5 bytes vs 7). – David Wohlferd May 08 '18 at 02:31
  • 2
    And while I'm thinking about it: If possible, consider using another register (say `rbx`) to hold the value of zero. `mov eax, ebx` only takes 3 bytes. Dedicating a register to hold zero might be overkill, but it's an option. – David Wohlferd May 08 '18 at 02:52
  • 2
    Never seen `xor rax,rax`, so I'm not sure why you think it is popular.. it's normally `xor eax,eax`, as it's 1 byte shorter. – Ped7g May 08 '18 at 07:55
  • `lea` from another register with a known small-integer value is an option for a 3-byte instruction. e.g. `lea eax, [rdx-3]` if RDX was known to be 3. Otherwise push/pop is a win for code-size vs. 5-byte `mov eax,0`, but only by 2 bytes and it's significantly worse. See [Tips for golfing in x86/x64 machine code](//codegolf.stackexchange.com/q/132981) for code-size optimization tips (many of which are harmful for performance; normally smallest is only a tie-breaker between otherwise-equal performance options.) – Peter Cordes Oct 24 '19 at 02:46

0 Answers0