When a program is compiled, the code eventually ends up as instructions that can be executed by the processor. When for example a C program that writes data to a file is compiled, what code is in the executable file, is it just the code to call the OS write? I have seen the comparable question that refers to use of Frameworks in the OS, I consider using framework one level too high, I want to know more specific on the lower level.
Yes, it's just code saying "do a write".
There is usually code for writing files, communicating with the network, the screen etc. within the operating system, so it would be a waste of time to reprogram those services in user space (and the kernel would probably not even let you). The interface between use space and the OS is usually a strictly defined API consisting of system calls which execute predefined routines in the kernel.
It is less about programming language and operating system. It's more about user space functions and operating system level functions.
User programs have user space functions.
User space functions call operating system level functions to perform OS-specific tasks.
A C program that wants to write to a file will end up calling the one or more operating system level functions to do the real work.
A Python program that wants to write to a file will most likely end up calling the same operating system level functions to do the real work.
An operating system essentially presents an API to programs, on how to get things done much in the same way that most programs have a standard runtime library so you don't have to code everything yourself. This typically includes things like converting a string of digits to an integer, and so on.
In the Unix world the term "system call" is used for invoking a method in this API. Many exist, typically in reading and writing files, reading input from the user, printing strings to the user, reading the computer clock, and giving safe, fair access to the hardware so you have the illusion that your program is started, do stuff, and eventually end, without having to know that other programs also run, the CPU takes turns executing them, they may also write files while your program does, etc.
The programming language "closest" to Unix would be C. If you want to work with low level programming this is a good language to do it in.
On modern processors, the CPU instructions that either perform or initiate input/output are privileged; in addition, the physical memory addresses that devices map onto is protected (in this case, by the operating system). Further, interrupt handling capabilities (which are used by the devices to signal to the processor that data and/or device is ready for more I/O), are also privileged.
Privileged instructions, memory addresses, and interrupt handlers cannot be executed in the user mode process that runs the application. Thus, the application can only request the I/O operation from the operating system, usually via a system call, or some form of secure request into the operating system to access privileged resources.
There generally will be libraries on both sides of the system call. In the user mode application, there will be some language and runtime libraries that perform formatting and serialization of content that ultimately invoke operating system routines via a privileged & protected (system) call mechanism. The operating system will have a set of routines that respond to the application's requests and ultimately access the device.
Typically for a C program to perform a write, that is accomplished in source code by calling a library routine, so the compiler compiles that high-level function call (the write) into a machine code function call, pretty much just like the translation/compilation of any other function call.
The function call binds to a library routine that ultimately makes a system call or privileged request into the operating system. These libraries themselves are sometimes written in (part in) assembly language so that they can use the system call mechanism, which is usually some special processor instructions that the compilers don't normally generate. (Some systems have C-compilers with extensions that allow them do make system calls without needing assembly language.)
This depends very much on what operating system and what language you're talking about. Other answers have explored what this means for common consumer systems (e.g Windows or Unix-type OSs), but there are some interesting alternatives out there. Some operating systems, for example, are written such that they can only run programs written in a specific language. In this case, the language is effectively part of the operating system, and there is no boundary between the two. The most recent well known such system was Microsoft's Singularity OS which used a modified version of C# as its integrated language. Older systems that were based on UCSD p-Code (a virtual machine implementation of the Pascal language) also blurred the boundaries in a similar way.