Search code examples
assemblyx86nasmcpu-registersmicro-optimization

how to zero out all the registers in assembly without multiple instructions?


im trying to clear all the registers using this assembly code:

xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
xor esi, esi
xor edi, edi

but is there any other effective way, like a single instruction or anything else


Solution

  • You missed ESP, out of the 8 general-purpose integer registers.

    No, there's no instruction to do this, and it would be bad design if Intel had included an instruction that only did that rare and obscure task. It would take transistors to decode and microcode to implement, and use up an opcode that could have been better used for some other instruction or future extension.something

    There is fninit for the x87 stack registers which marks them as "empty" but doesn't actually zero the underlying regs. And there's AVX vzeroall for the XMM/YMM0..15 vector registers (not YMM16..31 so with AVX512 it's not actually all). That's a partner to vzeroupper which exists to avoid SSE/AVX transition penalties, otherwise they wouldn't have added it.

    You'd want to do this once or twice in an OS kernel (e.g. for process startup before jumping to user-space, to avoid info leaks), and pretty much never in any other code.

    You could rep stosd or movdqa some zeros onto the stack for popa, possibly in fewer instructions than 7x xor-zeroing instructions. but worst code-size and certainly worse efficiency. xor-zeroing is literally as cheap as a nop on modern Intel CPUs.

    In a kernel, you'd probably already have a context-switch function, so you might take advantage of it by zeroing a context buffer and then calling the context-switch function to switch to it.