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, rbxinstead of numbers). It maps 1:1 to the instructions. - Example: The x86 instruction
B8 05 00 00 00loads 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