assemblyx86-64cpuid

When is lahf usable in x86-64 modes?


The description of the lahf instruction is:

This instruction executes as described above in compatibility mode and legacy mode. It is valid in 64-bit mode only if CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1

First question: What is compatibility and legacy mode? How are they different from real-mode and protected mode?

Second question: What does CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1 mean?


Solution

  • what is compatibility and legacy mode. How are they different from real-mode and protected mode

    An 80x86 CPU has multiple modes. The ones software developers might care about are real mode, protected mode and long mode; but there's also system management mode (mostly "firmware use only"), "inactive" (waiting to be started), etc.

    Protected mode has multiple sub-modes (16-bit, 32-bit, virtual8086).

    Long mode has multiple sub-modes (16-bit, 32-bit, 64-bit).

    "Legacy mode/s" refers to real mode and protected mode (and all of protected mode's sub-modes), and not long mode or any of its sub-modes; where code is either 16-bit or 32-bit (with other differences between real mode and protected mode that don't matter for most instructions and only matter for things like segment register loads and operating system kernels). The legacy mode/s exist to provide backward compatibility to old software/operating systems (e.g. MS-DOS won't support long mode and will use real mode, Windows95 won't use long mode and will use protected mode, etc).

    Compatibility mode/s refers to the 16-bit and 32-bit sub-modes of long mode. The compatibility mode/s (or, the 16-bit and 32-bit sub-modes of long mode) exist to allow a newer OS to execute programs designed for an older OS (e.g. to allow a 64-bit version of Windows to run applications designed for a 32-bit version of Windows). In this case the code is either 16-bit or 32-bit (like legacy modes); but it is unlike legacy modes because it's still using the long mode mechanisms for paging, interrupts, etc. Mostly; for compatibility modes the kernel is expected to be 64-bit even though the currently executing code isn't.

    Second question: what does it mean CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1

    The CPUID instruction returns information about the CPU. Because there's lots of information the information is split into groups/"leaves" where the value in EAX determines which information the CPUID instruction will return (and for some cases ECX also modifies which information is returned). The information is returned in general purpose registers (EAX, EBX, ECX, EDX).

    "CPUID.80000001H:ECX.LAHF-SAHF[bit 0]" means "the value returned by the CPUID instruction in the bit 0 of ECX, when CPUID is called with EAX=0x80000001" (and the LAHF-SAHF part is just the name that AMD decided to give that bit).

    In other words, your code might look like (Intel syntax assembly):

        mov eax,0x80000001
        cpuid
        test ecx,1           ;Is bit 0 (the "LAHF-SAHF" bit) set?
        je .noLAHF           ; no, LAHF is not supported