Forge

x86_32 Linux (ELF32, i686)

32-bit Linux target for compatibility with older systems.

Target Triple

x86_32-unknown-linux-gnu

Rust toolchain: i686-unknown-linux-gnu

Build

# Add target
rustup target add i686-unknown-linux-gnu

# Install 32-bit libraries
sudo apt-get install gcc-multilib g++-multilib libc6-dev-i386

# Build compiler
cargo build --release --target i686-unknown-linux-gnu

# Compile program
./target/i686-unknown-linux-gnu/release/forgec input.dev -o output --target x86_32-unknown-linux-gnu

Architecture Details

Property Value
Architecture i686 (Pentium Pro+)
Format ELF32
Endianness Little
Pointer Size 32-bit
Page Size 4 KiB
Calling Convention cdecl

Registers

Register Purpose Saved
EAX Return value Volatile
EBX Callee-saved Preserved
ECX Volatile Volatile
EDX Return high / volatile Volatile
ESI Callee-saved Preserved
EDI Callee-saved Preserved
EBP Frame pointer Preserved
ESP Stack pointer Preserved

Calling Convention (cdecl)

Syscalls

Linux syscalls via int 0x80:

Syscall EAX EBX ECX EDX ESI EDI
read 3 fd buf count - -
write 4 fd buf count - -
exit 1 code - - - -
mmap 90 addr len prot flags fd
socket 359 domain type protocol - -

Bare binary (raw) kernel

A flat x86_32 binary — not an ELF — for freestanding / boot scenarios loaded by a stage-1 boot sector + stage-2 loader (see examples/os32/). Build it with a custom linker descriptor rather than the --target preset:

./target/release/forgec kernel.dev -o kernel.raw \
    --linker examples/targets/x86_32-raw.fld

examples/targets/x86_32-raw.fld contains:

ARCH x86_32
FORMAT raw
HOSTED false
ENTRY _start
LOAD 0x100000

Memory model: the image is linked at LOAD (default 0x100000); the stage-2 loader is responsible for placing the bytes there and jumping to ENTRY _start. String literals are fixed up against LOAD, so keep LOAD in sync with where your loader actually maps the image.

Object Format

ELF32 with sections:

Limitations vs x86_64

Feature x86_64 x86_32
Pointer size 64-bit 32-bit
Registers 16 GP 8 GP
Float support ✅ SSE2/x87 ❌ Not implemented
GC ✅ ❌ (importing std.gc is a clean codegen error)
Register args 6 in regs 0 (all stack)
Red zone 128 bytes ❌
Syscall ABI syscall int 0x80

Standard Library

Module Support
std.io ✅
std.mem ✅
std.string ✅
std.math ✅ (int only)
std.alloc ✅ (free-list, 4-byte headers; no GC)
std.fmt ✅
std.volatile ✅
std.gc ❌ (clean codegen error)

Float Emulation

Not implemented. Float operations not available on x86_32 target.

Workaround: Use fixed-point arithmetic or compile for x86_64.

Code Generation

Build Requirements

# Ubuntu/Debian
sudo apt-get install gcc-multilib g++-multilib libc6-dev-i386

# Fedora/RHEL
sudo dnf install glibc-devel.i686 libstdc++-devel.i686

# Arch
pacman -S gcc-multilib

Testing

# Build for x86_32
cargo test --test integration -- --target x86_32-unknown-linux-gnu

# Or run specific test
cargo test --test integration hello_dev_compiles_and_runs_x86_32

Performance

Compatibility

Runs on:

Not compatible with: