EMZETT.
Login

Machine code

In short: Machine code is the sequence of binary numbers a processor can execute directly. All other programming languages must end up in this form or be run by a program that does so.

In more detail: A processor knows only its own instruction set, for example x86-64 (Intel/AMD) or ARM. Each instruction is a number: for example “add these two registers”. Machine code is therefore processor dependent and hardly readable for humans.

In Depth

From high-level language to machine code:

Source (C, Rust, Go)    ──compiler──►  machine code ──► processor
Source (Java, C#)       ──compiler──►  bytecode ──JVM/CLR (interpreter + JIT)──► machine code
Source (Python, JS)     ──interpreter──► executes statements (JS: JIT to machine code)
  • Assembly: A readable notation for machine code (add rax, rbx instead of numbers). It maps 1:1 to the instructions.
  • Example: The x86 instruction B8 05 00 00 00 loads the number 5 into a register (mov eax, 5).
  • Bytecode is not machine code: It is an intermediate format for a virtual machine and runs on the CPU only after translation.
  • Native programs: Compiled C, C++, Rust or Go programs contain machine code and start without a runtime. In return they are bound to processor and operating system.
  • Portability: An x86 program does not run on ARM unless recompiled or emulated (for example Rosetta on the Mac).
  • Viewing: objdump -d program (Linux) or a debugger shows machine code as assembly.
  • Memory: Machine code sits in memory in a region marked executable. The operating system forbids executing data areas (NX bit), which makes many attacks harder.

See also: Compiler, Bytecode, Interpreter