Suppose, I have a program written in C and I have two identical computers, the one is running Windows and the other is linux. Since the computers are identical, their processors have the same instruction set, so the machine code after compilation should be the same. So why do I need to compile my program twice? Suppose, I dont call any OS-related function, or something that depends on the actual OS.
Machine code does not depend on OS, it's same for the same CPU.
Machine code is dependent on the hardware, and cannot just be run on just any platform with the same OS, unless you're running a virtual machine that emulates the same hardware as that targeted by the machine code. The compiler does not produce machine code, rather it produces object code.
This is because Java compilers generate bytecode for the JVM, and are executed by the Java runtime (which is OS and processor specific). But the Java compiler (which is written in Java) can run on any machine, and generate code that will run on any machine. Thanks for your answer.
binary code, code used in digital computers, based on a binary number system in which there are only two possible states, off and on, usually symbolized by 0 and 1.
Machine code does not depend on OS, it's same for the same CPU.
If you did OS agnostic piece of machine code, in target CPU mode (let's say x86 32b), and load that into some ROM memory, so it will be available, you can map that part of ROM both in Windows and in linux (by completely different OS API to map physical memory and give it executable rights), and jump there.. and the machine code in ROM would run the same way.
So why do I need to compile my program twice? Suppose, I dont call any OS-related function, or something that depends on the actual OS.
You don't have to. But usually you want some entry point into your code, and usually the simplest way how to provide universal entry point is to follow the OS defined ABI (Application Binary Interface), so for example in 32b windows you read arguments from stack, and in 64b linux you receive arguments in registers (when possible). If you wouldn't adjust your procedure prologue code to pick arguments in correct way, it will operate with wrong inputs in the "other" OS than it is written for.
But the machine code itself, the CPU instructions, are same.
That said, on x86 the situation is a bit more hairy due to historical backward compatibility, so the CPU can be in 16b mode, 32b [protected] mode (couple of them plus differently set up), or 64b mode. The 80386 CPU instruction mov eax,1
has different machine code encoding for 16b mode, and for 32b mode.
But as long as you are targetting the same CPU mode, the machine code of the same instruction is compiled in the same way. You just write source differently to follow different ABI.
And the executable files... each format is different, it's not even "per OS", again due to historical reasons almost all x86 OS support several executable file formats, so the meta data around machine code stored in the file (to be used by OS during loading machine code into memory and setting it up for run) are completely different.
Practical example is linux app wine
, which can execute windows executables, by providing fake OS hook points to simulate windows OS, and by understanding windows executable binaries, so correctly loading them into memory. The machine code of such windows application is run natively, without any further patching.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With