General CS Notes

  1. Data Structures
  2. Python Data Structures
  3. Python Memory Management
  4. The Hardware-Software Interface

General CS Notes

The Hardware-Software Interface

Using this as a catch-all for “everything going on under the hood of a program,” so it’ll include lower-level process and OS-level stuff as well. May split off if there’s a good boundary, but easier not to at first.

Stack / heap

From the program’s perspective, there’s stack vs heap for where data is stored. The CPU doesn’t—in general—care about stack vs heap, or the cache vs RAM memory hierarchy. It just reads/writes from/to addresses.

The stack stores one top-level block of OS-written program/system metadata (args, env, name, page size, some random bytes), plus a frame for each function. Each frame has: stack metadata (ret and prev frame addrs), function-local vars and args, previous register values. (Interestingly: some registers are saved by the caller (volatile), and some by the callee (non-volatile; if it wants to use them).)

The heap stores larger data (allocated, arbitrary lifetime). (Interestingly, malloc is typically in userspace!)

In virtual address space, stack grows down from high (0xFFFFFFFF) and heap grows up from low. Stack and heap are typically read/write, but not executable (exception: JITs execute on heap). (Code lives in its own memory place (“text”), is read-only and executable.) The CPU doesn’t really care about where the stack/heap are; just memory addrs.

Both stack and heap support read/write memory operations. But many operations do explicitly operate on the stack. E.g., push/pop/call/ret read/write the stack pointer, and read/write the memory there. The OS sets up the stack, and the compiler emits code for managing the stack.

TODO: Add later:

Memory hierarchy

The memory hierarchy has different access speeds. Registers fastest (no delay), then L1, L2, L3 caches, RAM, disk, network. Furthermore, chunks of memory are loaded into faster at a time (pages; usually 4KB, though can tune up to MBs or GB). So accessing sequential values in a loaded page is fast — of course, must be done while the page is still there. (Spatial and temporal locality.)

The cache system (L1/L2/L3) intercepts and accelerates RAM lookups if possible. (Registers, though, are different in that they’re directly referenced in machine code, and compilers try to keep hot values in them.) So from both the programmer’s and CPU’s perspective, the caches are invisible and not referenced in code. But, of course, knowing their behavior helps optimize code.

Interaction with stack/heap: Are caches big enough to fit the whole stack? Sometimes yes, but it likely wouldn’t make sense. Only the “hot” portion of the stack is likely to be kept in the cache, because other frequently-accessed memory will want to be cached too: other processes’ stacks, hot heap data structures, program code, kernel data.

TODO: Add later:

C Memory Sizes

char is almost always 8 bits. C std: char is smallest addressable unit of memory.

int is usually 32-bits, even on 64-bit consoles (x86-64, arm64). For back-compat reasons. The C standard guarantees:

pointers (of course: 64 bits for 64-bit, 32 bits for 32-bit) can be found out with sizeof(void*).

word size (CPU register size) almost always == pointer size (memory address len). but they are technically different concepts. (rare past exception: old 16-bit x86 that could use 16 or 32-bit pointers.)

Here’s a summary table of typical values on modern 64-bit systems:

C Type Unix-like (bytes) Windows (if different)
bool 1
char 1
short 2
int 4
long 8 4
long long 8
float 4
double 8
long double 16 8
void * 8
size_t 8

Basic virtual memory layout

High Addresses
--------------------------------------------
| Stack (grows down) |
|------------------------------------------|
| |
|------------------------------------------|
| mmap region (shared libs) | (e.g. libc, ld.so)
|------------------------------------------|
| |
|------------------------------------------|
| Heap (grows up) | (starts empty)
|------------------------------------------|
| Uninitialized data (BSS) |
|------------------------------------------|
| Initialized data segment |
|------------------------------------------|
| Code / Text segment |
|------------------------------------------|
| NULL (0x0) |
--------------------------------------------
Low Addresses

The mmaped region is new to me. Interesting Q/A about mmap region:

TODO:

Getting memory

At program start, the heap address space is “reserved” (naturally via the memory layout) but begins empty.

malloc is a userspace program. This is cool, because it can be replaced. It’s in the a C std library, part of a suite: malloc, realloc, calloc, aligned_alloc and free.

An example of a malloc replacement is mimalloc, which Python adopted. (Unsure yet whether Python uses it to replace malloc, or as a higher-level allocator once they have a private heap, or both.)

Under the hood, malloc et al. use system calls to grow the heap’s size.

Manual regions

Note that some exist in multiple sections, so there’s man 1 read (default) and man 2 read.

Some of these are likely wrong, but it’s a useful overview.

Section Content Examples Frequency in Practice
1 General programs (including shell builtins) ls, grep, find, vim, cd Very High - Most commonly referenced
2 System calls (kernel functions) open, read, write, fork, execve High - Essential for system programming
3 Library functions (C standard library, etc.) printf, malloc, strcmp, signal, regex High - Critical for C/C++ development
4 Kernel interfaces (and (?) device files) null, zero, random, tcp, ip Low - Specialized hardware/driver work
5 File formats passwd, hosts, fstab, crontab, resolv.conf Medium - Useful for system administration
6 Games fortune, cowsay, sl, banner, factor Very Low - Rarely encountered
7 Miscellaneous (conventions, protocols, etc.) ascii, environ, hier, intro, time Medium - Helpful for understanding concepts
8 System admin commands mount, ifconfig, iptables, cron, systemctl Medium-High - Important for sysadmin work
9 Kernel developer’s manual (Linux-specific) kmalloc, copy_to_user, request_irq, mutex_lock Very Low - Kernel development only

post info


Published Aug 7, 2025
Disclaimer This is an entry in the garage. It may change or disappear at any point.
Inbound

General CS Notes series