On x86, Zircon needs to maintain the following invariants for code running in ring 0 (kernel mode).
These invariants are documented here because they are not necessarily easy to test -- breaking an invariant will not necessarily be caught by Zircon's test suite.
- Flags register: - The direction flag (DF) should be 0. This is required by the x86 calling conventions.
 - If this flag is set to 1, uses of x86 string instructions (e.g. - rep movsin- memcpy()or inlined by the compiler) can go wrong and copy in the wrong direction. It is OK for a function to set this flag to 1 temporarily as long as it changes it back to 0 before returning or calling other functions.- The alignment check flag (AC) should normally be 0. On CPUs that support SMAP, this prevents the kernel from accidentally reading or writing userland data.
 
- The - gs_baseregister must point to the current CPU's- x86_percpustruct whenever running in kernel mode with interrupts enabled.- gs_baseshould only be changed to point to something else while interrupts are disabled. For example, the- swapgsinstruction should only be used when interrupts are disabled.
- The following are partially enforced by the compiler: - No use of extended registers (SSE, AVX, x87, etc.) is allowed, because that would clobber userland's register state.
 - This is partially achieved by passing - -mno-sseto the compiler. This option is necessary to prevent the compiler from using SSE registers in optimizations (e.g. memory copies).- We would like to prevent accidentally using the - floator- doubletypes in kernel code, but GCC and Clang won't do that for us in all cases.- -mno-ssedoes not prevent using- float/- doublewith either compiler -- the compilers will use x87 instructions instead.- We compile with - -msoft-float, which seems to prevent GCC from generating x87 instructions (and hence using x87 registers): GCC 6.3.0 will give an error on- float/- doublearithmetic and return values, but it does not prevent passing these types around as arguments. However, passing- -msoft-floatto Clang seems to have no effect: Clang 7.0.0 will still generate x87 instructions (and use x87 registers) for code using- floator- double.- No storing data below %rspon the stack. Note that userland code can do this: the SysV x86-64 ABI allows functions to store data in the "red zone", which is the 128 bytes below %rsp. However, kernel code cannot use the red zone because interrupts may clobber this region -- the CPU pushes data onto the stack immediately below %rsp when it invokes an interrupt handler.
 - This is generally enforced by passing - -mno-red-zoneto the compiler.