如何区分MachineState的mem数组预存与加载的0值并传递全部有效内容
Got it, let's tackle this problem step by step. The root issue here is that your mem array starts fully initialized to 0, so you can't tell which 0s were part of the original default state versus which were explicitly loaded via your CADE/DADA instruction logic. Your current loop skips all 0s, so those intentionally loaded 0s never make it to UpdateMachineState.
Here are two practical, efficient ways to fix this:
Option 1: Add a Boolean Marker Array (Simple & Readable)
The most straightforward approach is to add a companion array to track which memory addresses have been explicitly loaded. This array acts as a flag for each address—true if the value was loaded, false if it's just the default 0.
Step 1: Update the MachineState Struct
Add a bool array (or uint8_t if you want to avoid stdbool.h) to your struct:
#include <stdbool.h> // Include this for bool type typedef struct { unsigned short mem[65536]; bool loaded[65536]; // Tracks if the address was explicitly loaded } MachineState;
Step 2: Initialize the Marker Array
Make sure to zero out both the mem and loaded arrays when initializing your state:
// For global variables, they'll auto-initialize to 0, but for local variables: MachineState state; memset(&state.mem, 0, sizeof(state.mem)); memset(&state.loaded, 0, sizeof(state.loaded)); // Set all flags to false initially
Step 3: Mark Loaded Addresses
Whenever you load a value (including 0) into mem[addr], set the corresponding flag to true:
// Example: After reading addr and value from the binary file state.mem[addr] = value; state.loaded[addr] = true; // Mark this address as intentionally loaded
Step 4: Adjust the Update Loop
Instead of checking if mem[addr] is non-zero, check if the loaded flag is true:
for (int addr = 0; addr < 65536; addr++) { if (state.loaded[addr]) { UpdateMachineState(addr, state.mem[addr]); } }
Option 2: Use a Bitmap (Memory-Efficient)
If memory usage is a concern (the boolean array takes 64KB), you can use a bitmap to track loaded addresses. A bitmap uses 1 bit per address, so 65536 bits = 8KB total—way more compact.
Step 1: Update the MachineState Struct
Replace the boolean array with a bitmap:
typedef struct { unsigned short mem[65536]; unsigned char loaded_bitmap[8192]; // 65536 bits = 8192 bytes } MachineState;
Step 2: Helper Macros for Bitmap Operations
Add macros to set and check bits in the bitmap (makes the code cleaner):
#define SET_LOADED(bitmap, addr) (bitmap[(addr)/8] |= (1 << ((addr) % 8))) #define IS_LOADED(bitmap, addr) ((bitmap[(addr)/8] & (1 << ((addr) % 8))) != 0)
Step 3: Initialize and Mark Loaded Addresses
Initialize the bitmap to 0, then mark addresses when loading:
MachineState state; memset(&state.mem, 0, sizeof(state.mem)); memset(&state.loaded_bitmap, 0, sizeof(state.loaded_bitmap)); // When loading a value: state.mem[addr] = value; SET_LOADED(state.loaded_bitmap, addr);
Step 4: Adjust the Update Loop
Use the IS_LOADED macro to check which addresses need to be passed to UpdateMachineState:
for (int addr = 0; addr < 65536; addr++) { if (IS_LOADED(state.loaded_bitmap, addr)) { UpdateMachineState(addr, state.mem[addr]); } }
Key Notes
- Initialization: Always zero out your marker array/bitmap—uninitialized memory will have random values that break your logic.
- Unloading Logic: If you ever need to "unload" a value from memory, remember to set the marker back to
false(or clear the bit in the bitmap). - Performance: Both options have minimal overhead—boolean array is slightly faster to access, while the bitmap saves memory. Pick based on your project's constraints.
内容的提问来源于stack exchange,提问作者J_code

