Your considerations look very true-like, but you are doing some implicit assumptions which break the logic. Basically, the considerations about 0s and 1s are irrelevant. Everything on a computer is made of 0s and 1s;
and OS calls are also made of those 0s and 1s. The question remain open: do you always need to do this call.
First of all, it is apparent: not always. You can create some limited class of "programs" (let's be more formal: executable files, PE files) which won't use any OS calls at all. And it even makes sense. What are the limitations? You won't be able to use any IO, in the sense of using system
peripherals, won't be able to allocate any memory (you cannot program without it, because you would then use the memory block allocated by the executable loader, part of OS), won't be able to create thread, use thread synchronization and communication with other processes (IPC). Without all that, you still can implement some useful algorithm (still, in a limited class, because even some formal and abstract algorithms need memory allocation, the use of
heap). You can
export any static functions doing any calculations; in EXE file, you can use its
entry point ("main" function) to output result of any calculations represented as one integer value. Other programs can use your module created under these limitations.
But you may still question: why not using I/O and all I described above as a set of limitations, in a fully stand-along application? In my interpretation, this is reduced to the question: where is your subtle logical mistake which led to not understanding why this is impossible? This is harder to explain.
The subtle mistake is: 1) you did not take into account that OS is not a set of executable file; the difference is: during OS
bootstrap,
part of OS becomes permanently loaded; 2)
you did not take into account hardware protection.
Note that most modern versions of Windows systems use Intel CPUs which has
protected mode. In protected mode, you can create some code or data
segments which are permanently closed for direct access from some other code segments. The protection cannot be bypasses, because it is implemented in hardware. Some part of software is loaded in so-called
kernel mode which confines access to many important resources inside certain
protection ring. All application processes can get access to such resource only indirectly, by delegating a request to the inner protection ring.
How is looks in practice? For example, in documentation, you can read absolute range of physical addresses of a video card and set of ports used for output to the screen. So, you can write to screen by setting certain screen modes using the port output CPU instructions, and write to physical address of the card to output characters and pixels. Well, try to do it. All you can get is access violation (in OS terms, it will be General Protection Fault). And, mind you, it will be a
hardware exception generated directly by the CPU. Such operations are reserved to the kernel only.
This is why would you need some OS calls. They actually delegate the access to the video card ports and memory to the kernel-mode part of OS. The CPU has the special mechanism for interaction between different rings. The physical access is done in kernel mode.
The system is much more complicated than I tries to describe. There are drivers; some of them are kernel-mode, and the drivers can be loaded dynamically, in a plug-and-play manner, without a need to reboot the OS. Yet, nothing on this level works without OS API. Also, all of the above is related to Windows and some other systems with similar approach, which also includes Linux. Some OS may not employ such protection.
To understand further detail, you would need to study CPU architectures and protected mode. To start with, please see:
http://en.wikipedia.org/wiki/Protection_ring[
^],
http://en.wikipedia.org/wiki/Protected_mode[
^],
http://en.wikipedia.org/wiki/Hybrid_kernel[
^] (the type of kernel of the modern Windows OS,
http://en.wikipedia.org/wiki/Windows_NT[
^].
—SA