NanoCore Maximum Program Size: Understanding the 256-Byte Address Space Limit
NanoCore enforces a strict maximum program size of 256 bytes, determined by a fixed memory: [u8; 256] array in the CPU struct, with the load_program method rejecting any program that would exceed this boundary when combined with its start address.
NanoCore is a lightweight educational CPU emulator written in Rust that simulates an 8-bit architecture with constrained memory resources. Understanding the maximum program size NanoCore can load and execute is critical for developing valid assembly programs and handling memory layout constraints effectively.
The 256-Byte Memory Architecture
The memory constraint is hard-coded in the CPU definition within src/cpu.rs. The emulator allocates a fixed-size array to represent the entire addressable memory space:
pub struct Cpu {
pub memory: [u8; 256], // 256 bytes of memory
// ... other fields
}
(see src/cpu.rs lines 24-26)
This design choice reflects the 8-bit architecture limitation, where memory addresses are limited to the range 0x00 to 0xFF (0–255). Because the address space is only 8 bits wide, the theoretical maximum directly addressable memory is 256 bytes, and NanoCore implements exactly this limit.
How NanoCore Enforces the Maximum Program Size
When loading a program via the load_program method in src/nanocore.rs, the emulator performs a bounds check to ensure the program fits within the available memory starting from the specified address:
if (start_address as usize + program.len()) > 256 {
return Err(crate::EmulatorError::ProgramTooLarge {
size: program.len(),
start: start_address,
max: 256,
});
}
(see src/nanocore.rs lines 92-100)
The validation calculates the end address by adding the program length to the start_address parameter. If this sum exceeds 256, the function immediately returns an EmulatorError::ProgramTooLarge error containing the attempted size, start address, and maximum allowed value.
Calculating Available Program Space
The effective maximum program size depends on where you load the program in memory:
- Loading at address
0x00: The full 256 bytes are available - Loading at address
0x10: Maximum size is 240 bytes (256 - 16) - Loading at address
0xF0: Maximum size is 16 bytes (256 - 240)
This calculation ensures that the program code cannot overwrite memory beyond the allocated array or collide with data regions you may reserve at higher addresses.
Maximum Size When Loading at Address 0x00
When you load a program at the beginning of the address space, you can utilize the full 256-byte capacity:
use nanocore::nanocore::NanoCore;
// Load the maximum-size program (256 bytes) at address 0x00
let mut emulator = NanoCore::new();
let max_program = vec![0x00u8; 256]; // 256-byte NOP-filled program
emulator.load_program(&max_program, 0x00).unwrap();
emulator.run().unwrap();
Loading at Non-Zero Start Addresses
If you reserve lower memory for data or stack space, you must account for the reduced available space:
let mut emulator = NanoCore::new();
let prog = vec![0x02, 0x00, 0x42, 0x00]; // LDI R0,0x42; HLT
// Fits because 0xF0 (240) + 4 = 244 ≤ 256
emulator.load_program(&prog, 0xF0).unwrap();
Attempting to load a program that exceeds the remaining space results in an error:
let mut emulator = NanoCore::new();
let oversized = vec![0x00u8; 257]; // 257 bytes, exceeds limit
let err = emulator.load_program(&oversized, 0x00).unwrap_err();
assert!(matches!(err, nanocore::EmulatorError::ProgramTooLarge { .. }));
Summary
- NanoCore provides exactly 256 bytes of addressable memory, implemented as a fixed array in
src/cpu.rs. - The
load_programmethod insrc/nanocore.rsvalidates thatstart_address + program_length ≤ 256before writing to memory. - Maximum program size varies by load address: 256 bytes at
0x00, decreasing linearly as the start address increases. - Exceeding the limit triggers
EmulatorError::ProgramTooLarge, preventing memory corruption or undefined behavior.
Frequently Asked Questions
What happens if I try to load a program larger than 256 bytes in NanoCore?
The load_program method returns an EmulatorError::ProgramTooLarge error containing the program size, requested start address, and the maximum allowed size of 256. The program is not loaded into memory, and the emulator state remains unchanged.
Can I increase the memory limit in NanoCore?
No, the 256-byte limit is fundamental to NanoCore's architecture. The memory is defined as a fixed [u8; 256] array in the Cpu struct, and address registers are 8-bit values. Modifying this would require changing the core data structures in src/cpu.rs and updating all address-handling logic throughout the codebase.
Why is the address space limited to 256 bytes?
The limitation reflects the 8-bit architecture simulation. With 8-bit address registers, the processor can only represent values 0 through 255, yielding exactly 256 unique memory addresses. NanoCore accurately models this hardware constraint to provide an authentic low-level programming experience.
How do I check if my program will fit before loading?
Calculate the end address by adding your program's byte length to the intended start address. If the result is less than or equal to 256, the program will fit. For example, a 100-byte program loaded at address 0x80 (128) occupies addresses 128 through 227, which fits within the 256-byte limit.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →