Because a register's value can change independently of your program (hardware updates status bits, a data register refills) and writes have side effects (driving pins, starting a conversion). Without volatile, the optimizer assumes a memory location only changes when the code changes it, so it may cache a register read in a CPU register and reuse the stale value, making a while (!(UART->SR & RXNE)) poll loop spin forever on a cached "not ready", or it may eliminate "redundant" writes and reorder accesses. volatile forbids all of that: every read and write to the register happens, in program order, exactly as written. It does not make the access atomic or insert memory barriers, that's a separate concern, it only guarantees the accesses occur and aren't optimized away. Vendor register-overlay structs mark every member volatile precisely so driver code is correct under optimization.
Embedded Systems Fundamentals · Interview question
Why is volatile required for register access?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
Registers & Memory-Mapped I/O
How writing a memory address turns on an LED: control/status/data registers, the volatile register-overlay struct, and the write-1-to-clear and atomic set/reset traps.