assemblywindbgarm64

Confusion over CPSR register for Aarch64: how to read it and encoding of the "ARM processor mode"


I'm working with the Aarch64 architecture. And if I understand correctly, CPSR (or "Current Program Status Register") is a status register that holds current status of the CPU core execution.

I can see that WinDbg displays two flavors of it: cpsr and spsr (the latter being "Saved Program Status Register", or the value of cpsr after an exception.)

I can also see the encoding of the bits N, Z, C, V in it.

But I'm somewhat puzzled by the encoding of the M[4:0], bits [4:0], or "ARM processor mode".

I can see that WinDbg gives me these values (when I break in kernel mode on Windows 11):

cpsr: 0x60000044
spsr: 0x60000044

So this would mean that the M bits are: 0b00100. But how can it be true, if according to documentation this is an undefined encoding?


And a small follow-up question on this subject.

I tried to read CPSR register directly from assembly:

mrs    x0, CPSR

But this instruction gives me this error during compilation:

error A2502: operand 2: Expected constant

What am I doing wrong there?


Solution

  • So this would mean that the M bits are: 0b00100. But how can it be true, if according to documentation this is an undefined encoding?

    You looked at the wrong documentation, your link is for ARMv7. If you look at ARMv8 and scroll past the 32-bit processor states, you see:

    M[4], bit [4]

    Execution state. Set to 0b0, the value of PSTATE.nRW, on taking an exception to EL1 from AArch64 state, and copied to PSTATE.nRW on executing an exception return operation in EL1. |M[4]|Meaning| |:-|:-| |0b0|AArch64 execution state.|

    On a Warm reset, this field resets to an architecturally UNKNOWN value.

    M[3:0], bits [3:0]

    AArch64 Exception level and selected Stack Pointer. |M[3:0]|Meaning| |:-|:-| |0b0000|EL0t.| |0b0100|EL1t.| |0b0101|EL1h.|

    So you're just in EL1 with SP0.


    But this instruction gives me this error during compilation:

    error A2502: operand 2: Expected constant
    

    What am I doing wrong there?

    CPSR doesn't exist in arm64. There's PSTATE which has about the same role, but that isn't a register either, it's "an abstraction of process state information". You can access certain parts of it through registers like NZCV, PAN or DAIF, but the only way to get or set it in its entirety is through SPSR_ELn and exception entry/return.