According to Robert Love, the author of the book Linux Kernel Development, and the Linux kernel source:
In the Linux kernel, specifically in the PCB (process control block), there is a structure that represents the process in the kernel: task_struct.
The six state flags
The process state is represented by a combination of six state flags:
- TASK_RUNNING: the process is currently running or ready to run.
- TASK_INTERRUPTIBLE: the process is waiting for a specific event to occur and can be interrupted by a signal.
- TASK_UNINTERRUPTIBLE: the process is waiting for a specific event to occur and cannot be interrupted by a signal.
- __TASK_STOPPED: the process has been stopped (e.g. by a SIGSTOP signal) and can be resumed later.
- __TASK_TRACED: the process is being traced by another process (e.g. a debugger).
- TASK_DEAD: the process has terminated and is waiting to be reaped by its parent process.
Combining flags
Each of these flags can be set or cleared to represent the different states a process can be in. For example, a process that is both TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE might be waiting for a disk I/O operation to complete, and can be interrupted by a signal but cannot be killed until the I/O operation is finished.
In other words, a process can have multiple states at once, depending on which combination of flags is set.
So why 4 bytes?
This state is saved in an unsigned integer. That means 32 bits, which means 2³² possible values. But we only need 2⁶, so 64 possible states as a maximum.

The reason is the following:
There are some predefined functions that manage the process’s state, such as READ_ONCE/WRITE_ONCE, that oblige this variable to be an unsigned int. It used to be a volatile long. Here is the commit:
Thank you for reading <3
