Forgive my ignorance.... The following retrieves information from a x86/x86_64 processor. Its used in an inline assembly block under Linux. The function is also inlined in a header. The other detail is, its System V ABI, so the caller owns RBP, RBX and R12-R15 under x86_64 (I'm not sure about the i386 variant). struct CPUIDinfo { word32 EAX; word32 EBX; word32 ECX; word32 EDX; }; .... static inline void CpuId(unsigned int func, unsigned int subfunc, CPUIDinfo& info) { __asm__ __volatile__ ( "cpuid" : "=a"(info.EAX), "=b"(info.EBX), "=c"(info.ECX), "=d"(info.EDX) : "a"(func), "c"(subfunc) : "b" ); } The CPUID instruction always uses EAX/EBX/ECX/EDX, even on 64-bit platforms. On 64-bit platforms, the CPUID instruction sets the high 32-bit words of RAX/RBX/RCX.RDX equal to 0. My question is, will the extended assembly preserve the registers? Is it sufficient to list "b" as a clobber? Or do I need to do something special? If I need to do something special, then what needs to be done? (I also looked at https://gcc.gnu.org/ml/gcc-patches/2007-09/msg00324.html, which is a GCC patch for cpuid.h. But its not clear to me if the above is correct because the operands are 32-bit in size. Naively, if I use "a" and "b" with a 32-bit operand, then I would expect code for EAX and EBX; and not RAX and RBX). Thanks in advance.