In the beginning there was a CPU. And the CPU could be loaded with data which were numbers and these magical numbers would cause the CPU to process those numbers and produce new numbers. This data which the CPU was running, the numbers fed into the computer, was machine code. And all programming of computers that's still done today ultimately ends up turning into machine code for the CPU, binary machine code being the only thing a computer can understand.
But long series of numbers, where each 256 or more unique numbers has special meaning which changes depending on context such as what number came before it, this is too difficult for humans to remember and reason about efficiently. It's too far separated from the way humans think. So we name these numbers, and these mnemonics are far easier to remember. We just need to assemble these mnemonic words for number along with other names and values into machine code. Thus assembly language is born.
Each processor has its own machine code format and so each type of CPU has its own unique assembly language to go with it. There is no global standard for machine code because that would prevent CPU manufacturers from adding new instructions which allowed CPUs to do new things. But what if we could have a virtual CPU with its own unique instruction set (machine code language) which could be turned into the machine code for any CPU family to finally run on a real CPU? And so the Java Virtual Machine (JVM) was born.
The JVM is possible in part due to being a stack-based architecture without registers. Generally, CPUs have a number of memory slots called registers where they can hold a few numbers for immediate use. But each CPU architecture can have any number of registers. The JVM relies on no registers and instead stores values on a stack. Thus the JVM can run on any architecture with a stack, which is all of them. Using the stack instead of registers also means the bytecode can be shorter due to not having duplicate instructions for combinations or registers as arguments or adding bytes to refer to the registers for each instruction. But you need to add extra code to push and pop values on the stack. Android and Dalvik VM which is a JVM implementation using registers rather than the stack does so to reduce the size of the code, not require JIT re-compiling and optmization for registers, and faster execution. But this means that the universal bytecode of the standard JVM is different from Android VM bytecode.
Nobody actually programs Java Virtual Machines by writing bytecode - which is what we call JVM machine code. Nor do they write JVM assembly language code and assemble into JVM bytecode (although you can do this with a tool called Jasmin). The JVM was created for its own programming language, Java. Nowadays, a number of languages can compile to JVM bytecode, and Java itself can compile directly to machine code (via gcj, the GNU Java compiler).
These large code bases like games or DOS emulators weren't written from scratch in asm.js, although it's possible to write asm.js by hand. But asm.js takes advantage of tons of existing software written in C/C++ by using the Emscripten compiler to take C and compile it to an asm.js target. This already works, although for now only in Firefox.
But as we try to run larger and larger asm.js software, we have more performance problems. One problem is the loading time, the thing that suppressed Java applets back in the day. And so for quicker downloads and loading as well as overcoming the parse time overhead, browser vendors like Google, Microsoft, and even Mozilla, want to go beyond asm.js. This next idea is called WebAssembly.
Machine code has been real since the beginning. Bytecode has been tested, rolled out, and matured in the hands of much of the world in the form of Java. Asm.js is new, but you can download and run it today using Firefox. WebAssembly hopes to be the future binary code format, but it's still early days and playing with it is still confined to developers only.