I always wondered about how executable binary files actually work. Compilation is always stated as

taking the source code and translating it to machine language

But what does that really mean? Namely:

  1. Can I move a binary file from computer A to computer B and expect it to work? (assuming that I also move the appropriate libraries)
  2. Is every executable binary file made to work with a specific processor?
  3. What sort of information is inside an executable binary file?
  4. How come executable files on windows can be launched on any windows version? (It's an other story if they work)
  5. Why can't I run a Linux executable on Windows? Does it have to do with the kernel(so not the processor)?

Mind that I have limited knowledge on processors and compilers and none on assembly.

  • The answer to the last question is obvious. Linux cannot use Win32 library files, thus any application designed to launch on Windows, cannot be launched on Linux unless the reference to those Win32 library files are removed. I am not sure what the question is to be honest. – Ramhound Jul 25 '14 at 10:54
  • Yes, a program has to be compiled for a specific chip, but it also has to target a specific operating system. You normally need the abstractions (the API) that an OS provides for you to do anything substantial on a machine, i.e., you need to link the binary library files that the OS provides into YOUR executable. Binary executable files are machine AND OS dependent and the OS loads them into memory and runs them, largely using the abstractions that the OS provides. – ChetPrickles Jun 4 '20 at 2:17
  1. Not necessarily. If it's build for portability and the platforms are compatible, then yes (e.g. 64 bit editions of Windows are able to execute 32 bit and 64 bit Windows executables, but not 16 bit ones anymore).
  2. Not necessarily. They're made for a specific instruction set. Since those are typically extensions and there's backward compatibility, you might run older files on newer processors, but not necessarily the other way around. For example, a program compiled for Windows 95 will probably still run on today's hardware, but you can't run a program compiled for today's hardware on an old Windows 95 machine. However, if two machines run completely different instructions, the executables won't be compatible (e.g. Intel vs. ARM).
  3. This is platform dependent, there are multiple formats with different headers and stuff, but basically there's always some kind of header working as an index, telling the operating system where to find specific things (such as the main entry point).
  4. They actually can't (see #2 above).
  5. First of all, Windows and Linux use different formats for their executable files. But even then there are differences, for example the whole environment and provided platform API/libraries. For example, a Linux executable would typically try to talk to a window manager such as X11, while a Windows program would try to call the Windows API. However, there are ways to get such things working. Older versions of Windows (NT?) actually had POSIX extensions so you could run a limited set of Linux programs as far as I'm aware, although I've never really tried that or had a closer look. On the other side, for Linux there are tools such as Wine, which will try to emulate the Windows environment, providing the API files, path conversions, etc. It's no complete emulation (like in using a virtual machine).
  1. Only under very controlled circumstances: Both computers must have a compatible processor and operating system.

  2. Not a specific processor, but a set of compatible processors. E.g. a file compiled for compatibility with x86 and no extensions will work on every Intel or AMD x86 or x64 processor, assuming the OS is compatible.

  3. First and foremost the machine code from the compilation step. In addition to that, a few other socalled "sections" will have e.g. resources (ever wondered, why an executable has a dedicated Icon on Windows, even if it is not running, but just shown in explorer), the description of binary compatibility and more.

  4. This is a side effect of 1.: Whenever the OS provides compatibility with the executable format, it can be launched. Modern Windows versions provide a range of compatibility: DOS, Win16, Win32, Win64, dotnet are the most important ones.

  5. The OS provides the executable with an environment, that is indispensable for execution. Those environments differ wildly between Linux and Windows. This means, you can't directly run executables from one on the other. There are projects underway to bridge this gap: The WINE project aims to allow launching of Windows executables on Linux (and other OSes), while the Cygwin project aims to make it possible to run Linux software on Windows. Cygwin doesn't aim for binary compatibility, but to allow for recompilation of unmodified source.

It is importand to understand, that the executable (e.g. the .exe) is not the result of the compilation process - it is the result of the linking process, which combines the output of compilation with the other ingredients needed to create what I described in 3.

Not the answer you're looking for? Browse other questions tagged or ask your own question.