I’ve been reading up on assembly. From what I understand about programming languages, it seems that compilers (assemblers… I know there are subtle diffrences between the two argued elsewhere), produce object code. An unfriendly slew of machine language void of directives. This object code is interpreted by the processor, after which a linker makes it an executable. I know each processor must be spoken to in its correct assembly. Ie. .386, .486, .586 The thing which puzzles me is the diffrence between running DOS programs through MASM and running the same program through Linux without NASM or GAS. If the source code is compiled into object code isn’t it cross platform at this point? I can dual boot Windows off my Dell just as easy as Linux. What am I missing here?
Also I have been looking for a way to view the object code, so that I don’t have to decipher the execution through Immunity Debugger. Just the Directive for Directive machine code for the source code I wrote. Are there any ways to produce a result like objdump in Linux?
A modern “x86” chip understands at least three distinct instruction sets – a 16 bit one used by DOS, and 32 and 64 bit ones used by various flavors of windows & linux.
Even though the chip is the same, and might be running in the same mode, the way a program interacts with the host operating system to obtain services (such as input/output) is quite different.
All but the most trivial programs tend to make use of external libraries of additional object code which provide assistance with common operations (string operations, formattted input and output, math, non-trivial networking, etc) so that they don’t have to be written from scratch. But the precise collection of such libraries available, and as importantly the means of requesting and interacting with them, differs depending on the host operating system. You can perhaps package the libraries with your application (static linking) instead of using .DLL’s/.so’s expect to already be on the system (dynamic linking), but the difference in requesting the underlying raw operating system services would still need to be accommodated.
Additionally, some schemes such as java and .net create object code which runs on a virtual machine, or simulated processor, rather than directly on the physical processor. To some extent these are portable, if the virtual machine engine and support libraries are available in compatible forms.
The mingw version of objdump runs on windows and processes windows executables and is part of a tools suite for building windows programs with linux-like semantics. There is also a cross version of it which runs on linux and processes windows files. Going the other way, the WINE compatibility layer can run many windows executables on linux – you could explicitly test against that. But if you are willing to write in C against posix interfaces (or use a lot of wrappers on OS functions with assembly) you should be able to have one codebase that builds with both the linux and cross or mingw versions of gnu tools, so that you can relatively efficiently generate binaries for both operating systems.