Algorithms | Apple | AssemblyLanguage | BASH | Bash Cookbook | C-Programmming | CommonLisp | Computer Security | CuisSmalltalk | Databases | Emacs | Exploitation | Firewalls | Fortran | Functional Programming | Git | GNUSmalltalk | Haskell | Social Engineering | Javascript | Julia | Linux | Machine Learning | Metasploit |Machine Learning | Networking | Operating Systems | Open Data Science | Odin | Picolisp | Pharo Smalltalk | Purescript | Python | Racket | Scheme | Unity | vim | V | Web Development | Windows WSL | Zig
Assembly Languagess
Here is the truth about assembly: it is not a language so much as a set of labels for the machine’s own instructions. Every program you have ever run, in Python, PicoLisp or JavaScript, ends up as these instructions. Assembly is just the version written for people to read.
What it is, in plain words
A CPU understands only machine code: numbers that encode instructions like “add these two registers” or “jump to this address if the last result was zero”. Assembly language gives each instruction a short name (a mnemonic) such as mov, add, cmp, jne, call, ret, and lets you use labels instead of raw addresses. An assembler (GNU as, NASM, FASM) translates the text into machine code, almost one line to one instruction.
There is no single assembly language. Each CPU family has its own instruction set architecture (ISA):
- x86-64 (Intel, AMD) – most desktops and servers.
- AArch64 / ARM64 – phones, Apple Silicon Macs, Raspberry Pi 4 and 5, and a growing share of cloud servers.
- RISC-V – the open ISA, now shipping in boards and microcontrollers and well worth learning in 2026.
The notes at the bottom of this page are 32-bit x86 (ebp, esp). On 64-bit x86 the same registers are rbp and rsp, there are sixteen general registers instead of eight, and function arguments arrive in registers (rdi, rsi, rdx, rcx, r8, r9) rather than on the stack.
Why it matters
- Debugging. When a program crashes with no source, GDB and objdump show you assembly. Reading it is the last line of understanding.
- Performance. Seeing what the compiler produced shows whether a loop was vectorised or a function inlined.
- Security. Exploits, shellcode, reverse engineering and malware analysis all live here (see Computer Security and Types of Malware).
- Understanding. Stacks, calling conventions, pointers and system calls become concrete. This is the floor of Build a Computer in Your Head.
An everyday analogy: a calculator with a notepad
Imagine a calculator with a few memory buttons (registers), a big notepad (RAM) and a list of numbered instructions you follow one line at a time. “Copy the number from page 40 into memory A. Add memory B. If the result is zero, skip to line 12.” That is all a CPU does, billions of times a second. Assembly is writing out that list of instructions yourself.
A hands-on example: hello, world with no C library
# hello.s -- x86-64 Linux, GNU assembler (AT&T syntax)
.globl _start
.section .rodata
msg: .ascii "Hello from asm\n"
len = . - msg
.text
_start:
mov $1, %rax # syscall number 1 = write
mov $1, %rdi # fd 1 = stdout
lea msg(%rip), %rsi # buffer
mov $len, %rdx # length
syscall
mov $60, %rax # syscall 60 = exit
xor %rdi, %rdi # status 0
syscall
as hello.s -o hello.o && ld hello.o -o hello && ./hello
ls -l hello # a few hundred bytes, no libc at all
strace ./hello # exactly two system calls
Then go the other way and see what C becomes:
echo 'int sq(int x){return x*x;}' > sq.c
gcc -O2 -S -masm=intel sq.c -o - | grep -A3 'sq:'
# sq:
# imul edi, edi
# mov eax, edi
# ret
The argument arrived in edi, the result leaves in eax. That is the System V calling convention used on Linux, macOS and the BSDs.
Common misconceptions
- “Assembly is always faster.” Modern compilers usually beat hand-written assembly for general code. Hand-tuning pays off for small hot loops, SIMD and cryptography.
- “There is one assembly language.” There is one per ISA, plus two syntaxes for x86 alone: AT&T (
mov $1, %rax, GNU default) and Intel (mov rax, 1, NASM and most manuals). - “Assembly is the same as machine code.” Close, but the assembler also handles labels, directives, data and relocations for the linker.
- “Nobody writes it any more.” Kernels, bootloaders, compilers, codecs, crypto libraries and PicoLisp’s own low-level layer all contain it.
Connections
- Build a Computer in Your Head, Operating Systems, Cool Hardware.
- The Compiler, C Programming, objdump, Using the C Debugger.
- PicoLisp Assembly and The PicoLisp Machine – a Lisp built close to the metal.
- Forth – a language that feels like a portable assembler with a REPL.
Links, Sources and Reading List
- x86Asm Tutorial form wisc.edu
- x86 Guide from Virginia.edu
- Asm7
- springer books pdf on Linux ASM
- spring books pdf on A Concise Guide to ASM
- Links to Linux & i586+ Assembly Programming & Doc’s
- Excellent Free Tutorials to Learn Assembly - LinuxLinks
- https://en.wikipedia.org/wiki/META_II
Some Notes:
ebp is known as the base pointer or the frame pointer.
1. On entry to your function, you push it (to save the value for the calling function).
2. Then, you copy esp, the stack pointer, into ebp, so that ebp now points to your function's stack frame.
3. At the end of your function, you then pop ebp so that the calling function's value is restored.
For some clarification on exactly what is going on -
the push instruction:
1. puts the value from the specified register (ebp in this case), onto the stack, and
2. decrements the stack pointer by the appropriate amount.
The pop operation is the opposite -
1. it increments the stack pointer and takes a value from the stack and
2. puts it in the specified register.
