If program C can work directly on how the kernel can handle the allocation of resources for this program.
The kernel is responsible for managing the resources of the computer as a whole, including resources such as hardware. This means that for user-level applications to access things such as hardware devices, writing to a terminal, or reading a file, they must ask the kernel for permission. This is done using system calls opened by the operating system, as pointed out by @Marcus.
However, I would not say that the program runs directly on the hardware level in the sense that it does not interact directly with the hardware, since there will be a kernel module / driver. The client program will configure the arguments for the system call, and then interrupt the kernel and wait for the kernel to service the interrupt request made by the program.
That's why the OS today works in protected mode, unlike the old days, when they started in real mode, and the program could, for example, get confused with hardware resources directly - and potentially damage things.
This difference becomes very clear if you try to write the trivial program "hello world" in the x86 assembly. A few years ago, I wrote and documented this , reproduced below:
; ; This program runs in 32-bit protected mode. ; build: nasm -f elf -F stabs name.asm ; link: ld -o name name.o ; ; In 64-bit long mode you can use 64-bit registers (eg rax instead of eax, rbx instead of ebx, etc.) ; Also change "-f elf " for "-f elf64" in build command. ; section .data ; section for initialized data str: db 'Hello world!', 0Ah ; message string with new-line char at the end (10 decimal) str_len: equ $ - str ; calcs length of string (bytes) by subtracting the str start address ; from this address ($ symbol) section .text ; this is the code section global _start ; _start is the entry point and needs global scope to be 'seen' by the ; linker --equivalent to main() in C/C++ _start: ; definition of _start procedure begins here mov eax, 4 ; specify the sys_write function code (from OS vector table) mov ebx, 1 ; specify file descriptor stdout --in gnu/linux, everything treated as a file, ; even hardware devices mov ecx, str ; move start _address_ of string message to ecx register mov edx, str_len ; move length of message (in bytes) int 80h ; interrupt kernel to perform the system call we just set up - ; in gnu/linux services are requested through the kernel mov eax, 1 ; specify sys_exit function code (from OS vector table) mov ebx, 0 ; specify return code for OS (zero tells OS everything went fine) int 80h ; interrupt kernel to perform system call (to exit)
Notice how the program sets up the sys_write write system call and then tells the file descriptor where to write, being stdout , the line to write, etc.
In other words, the program itself does not perform a write operation; he installs things and asks the kernel to do this on his behalf, using a special interrupt, int 80h .
A possible analogy here may be when you go to a restaurant. The server will accept your order, but the chef will be the one to cook. In this analogy, you are a user application, the server accepting your food order is a system call, and the chef in the kitchen is the core of the OS.
If the executable file created from gcc is in a clean machine in an understandable form, then how to use privileged and unprivileged mode to work?
Disconnecting from the previous section, user level programs always start in user mode. When a program needs access to something (for example, a terminal, reading a file, etc.), it sets things up, as in the example with sys_write above, and asks the kernel to do this on its behalf with interruption. Interruption causes the program to enter kernel mode and remain there until the kernel completes servicing the client request, which may include refusing it at all (for example, trying to read a file that the user does not have the right to read).
Internally, this is the system call responsible for issuing the int 80h . User-level applications simply see a system call, which is the common interface between the client and the OS.
How does the kernel control the resolution of hardware resources when a program can directly work on hardware not through the kernel?
If you followed the previous explanations, now you can see that the kernel acts as a gatekeeper and that programs “tapped” these gates with the int 80h .