Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are executables in machine code operating system dependent?

In windows, when I compile a simple 'C' program, I get the final executable machine code .exe . The same thing using gcc in unix yields a .out machine code file.

What's the difference between these?

My basic question is, .exe and .out being machine codes, why are they operating system dependent?

As in, in Unix I cannot execute .exe directly and in Windows, I can't execute .out of Unix. Why is this so?

like image 640
Manish Mulani Avatar asked Feb 23 '11 20:02

Manish Mulani


2 Answers

It all has to do with how the program is loaded.

Windows and Linux have different formats for how they want a program to define itself.

In Linux, the ELF format is normally used. For Windows it is PE.

These formats define different data about the program that is needed to execute the machine instructions.

Also, the operating system interfaces are different, so different libraries need to be used and different system calls need to be made.

For a simple program, you can usually just recompile on the other operating system to have it work on both, but you will not be able to use a single file on both.

like image 80
Alan Geleynse Avatar answered Sep 28 '22 04:09

Alan Geleynse


The operating system abstracts access to the underlying hardware, and makes it available to programmers via system calls. In Windows, these are done through the Windows API (which is usually further abstracted by libraries that make programming easier, like MFC, etc). In UNIX, this is often done through interrupts, which the system's C library makes a bit easier by following the POSIX api (often with a few system-dependent additions).

For example, on Linux, system calls are made through int 0x80, with several registers being loaded with the arguments to the function, and the C library makes this easier by allowing you to call, e.g. read, with the expected arguments ( int fd, void *buf, size_t count ). This gets translated into an interrupt call, which the kernel responds to.

These two manners of making requests against the operating system are incompatible, and thus you (generally) can't run a Windows executable on UNIX systems, and vice versa, without using some additional system that acts as a translation layer, like WINE, VMWare, etc. (though the way those two work is very different).

(Incidentally, a.out says nothing about the contents of the executable; it's the traditional filename given to executables compiled on UNIX systems, and is short for "assembler output". GCC allows cross-compiling, so you can even compile Win32-compatible .EXE files with it. You can use the -o flag to gcc to specify the output filename, which shows you that it has no bearing on the actual format of the outputted file.)

like image 42
Sdaz MacSkibbons Avatar answered Sep 28 '22 04:09

Sdaz MacSkibbons