Is OS mode required for accessing general purpose registers
Computations on general-purpose registers ((a), (b), (d)) doesn't require any privileges.

Input/output requires privileges, to access a peripheral or to communicate with the part of the system that manages files. So (c) does generally require going to kernel mode. It's possible for some printf calls to remain entirely within the calling process, for example if output is buffered and the output of this call is going entirely inside the buffer. But in general a printf call does need to do actual I/O and thus does need a transition to kernel mode.

A processor does not really “have more than one process executing at the same time”. The processor alternates between executing different processes, but at a given point in time, it's only executing one process (or it's in kernel mode). On a multiprocessor machine, each processor¹ executes one process at a given time, but the different processors can be executing different processes. While a process is executing, it can access the general-purpose registers directly. It doesn't need the kernel for that. (And how would it ask the kernel, anyway? A process communicates with the kernel by placing the parameters of a system call in general-purpose registers and then invoking the system call instruction.)

Processes execute code as if the other processes didn't exist. When the kernel decides to switch to another process, it suspends the running process and unsuspends the process that it wants to run next. Part of this suspension mechanism is to save the values of the general-purpose registers into a dedicated memory area that belongs to the process that is being suspended. There is one such register store for each process². Part of the unsuspension mechanism is to restore the registers of the process that is being unsuspended. When a process is unsuspended, it keeps running where it left off, with the same values in registers as when it was suspended. This suspension/unsuspension mechanism is called a context switch.

A process never overwrites the registers used by another process because only the currently running process's register values are in the processor registers. The other processes' register values are in their register store. There has to be a context switch to change which process's register values are in the processor registers.

Switching between processes does not involve semaphores. It's the other way round: in order to use semaphores to synchronize between different processes, the processes need to call the kernel.

¹  Each core, each thread — whatever you call the single-threaded processing unit. 
²  More generally, for each kernel thread.