⚙️
Assembly Language
2024 — Base64 Encoding/Decoding in x86-64 Assembly
About
Low-level implementation of Base64 encoding and decoding in x86-64 Assembly (NASM). Understanding computing at the hardware level — manipulating bits, bytes, and registers directly.
🎮 Live Demo
Try the same algorithm implemented in the assembly code:
Encoded (Base64):
QVMxNjQwNzM=
Decoded back:
AS164073
How Base64 works
Every 3 bytes (24 bits) are split into 4 groups of 6 bits. Each 6-bit value (0-63) maps to a character: A-Z (0-25), a-z (26-51), 0-9 (52-61), +/ (62-63). Padding with '=' if input isn't divisible by 3.
💻 Running on Linux
$ nasm -f elf64 base64_encode_linux.asm -o encode.o
$ ld encode.o -o encode
$ ./encode
Input: AS164073
Encoded: QVMxNjQwNzM=
$ nasm -f elf64 base64_decode_linux.asm -o decode.o
$ ld decode.o -o decode
$ ./decode
Encoded: QVMxNjQwNzM=
Decoded: AS164073
Code Sample: Encoding 3 Bytes
; Load 3 bytes into rax, convert to 4 base64 chars
mov al, [input + rcx] ; First byte
shl rax, 16
mov bl, [input + rcx + 1] ; Second byte
shl rbx, 8
or rax, rbx
mov bl, [input + rcx + 2] ; Third byte
or rax, rbx
; Extract 6-bit groups and lookup in table
mov r9, rax
shr rax, 18 ; Bits 23-18 → char 1
and rax, 0x3F
mov al, [table + rax] ; Lookup in Base64 table
mov [output + rdx], al
📊 Bit Manipulation
Converting "AS1" (3 bytes) to Base64 "QVMx" (4 chars):
| Input bytes: | 01000001 01010011 00110001 | A=65, S=83, 1=49 |
| 6-bit groups: | 010000 010101 001100 110001 | 16, 21, 12, 49 |
| Base64 chars: | QVMx | table[16,21,12,49] |
What I Learned
- • Direct register manipulation (RAX, RBX, RCX, RDX, RSI, RDI)
- • Bit shifting operations (SHL, SHR) for extracting bit groups
- • Linux system calls (syscall) for I/O without libc
- • Memory addressing modes and the x86-64 ABI
- • How high-level operations map to machine instructions
Tech Stack
x86-64 Assembly
NASM
Linux Syscalls
Bit Manipulation