An experimental framework for digital evolution, built in Rust.
Inspired by biological DNA and the Von Neumann brain theory, AsmDna combines interpreted RISC assembly languages running on multi-threaded micro-virtual machines with mutagenic evolutionary computation. It enables the creation of adaptive agents that evolve through mutation, selection, and resource competition, primarily compute time and memory usage.
This project explores the intersection of digital biology, low-level computing, and emergent intelligence to test how complex behaviors can arise from simple rule-based systems in a scalable, efficient environment reminiscent of a primordial soup. Built entirely with Rust, AsmDna implements a custom interpreted RISC assembly language within multi-threaded micro-virtual machine clusters.
Agents are initialized with a "genome" (a sequence of machine instructions), memory ("tape"), and registers. They evolve more efficient code to solve specific computational tasks through genetic algorithms. To maximize performance, my framework leverages 'repr(C)' and cache-aligned structures for improved memory efficiency and CPU utilization, creating a high-performance, open-source environment dedicated to advancing AGI research.
https://crates.io/crates/asmdna
- Custom Risc Assembly Language: A low-level instruction set designed for maximum flexibility and performance.
- Genetic Evolution: Built-in mutation engine that supports insertion, deletion, point mutations, and genome rearrangement.
- Multi-Threaded Micro-Virtual Machine: A cluster of VMs that can run in parallel, simulating a population of agents.
- Resource Management: Agents are managed with strict quotas for CPU cycles (
ns_units) and memory (byte_units). - Effective Design: Uses
repr(C)andrepr(align)structs to ensure cache-line efficiency and predictable memory layout.
This project was a second attempt, with the lessons learned from my first framework, based off a similar idea. https://github.com/had2020/Neurocrypt-Genesis
Currently one of my next project is complex physics simulation in a 3D space, to futher test my theory. It will be linked here once public!
The Dna enum defines the instruction set for the AsmDna VM. Each instruction is a 32-bit codon composed of an opcode and arguments.
| Opcode (Hex) | Mnemonic | Description | Operands |
|---|---|---|---|
0x00 |
MOV |
Move data between registers or immediate values. | dist, arg1 |
0x01 |
ADD |
Add two values and store result. | dist, arg1, arg2 |
0x02 |
SUB |
Subtract two values and store result. | dist, arg1, arg2 |
0x03 |
MUL |
Multiply two values and store result. | dist, arg1, arg2 |
0x04 |
DIV |
Divide two values and store result. | dist, arg1, arg2 |
0x05 |
MOD |
Modulo of two values and store result. | dist, arg1, arg2 |
0x06 |
POW |
Raise a value to the power of another. | dist, arg1, arg2 |
0x07 |
AND |
Bitwise AND of two values. | dist, arg1, arg2 |
0x08 |
OR |
Bitwise OR of two values. | dist, arg1, arg2 |
0x09 |
XOR |
Bitwise XOR of two values. | dist, arg1, arg2 |
0x0A |
NOT |
Bitwise NOT of a value. | dist, arg1 |
0x0B |
LSH |
Left Shift. | dist, arg1, arg2 |
0x0C |
RSH |
Right Shift. | dist, arg1, arg2 |
0x0D |
LD |
Load value from the Data Tape at TapePtr. |
dist |
0x0E |
ST |
Store dist into the Data Tape at TapePtr. |
dist |
0x0F |
INCPTR |
Increment the Data Tape pointer. | - |
0x10 |
DECPTR |
Decrement the Data Tape pointer. | - |
0x11 |
JLT |
Jump if dist < arg1. |
dist, arg1 |
0x12 |
JLE |
Jump if dist <= arg1. |
dist, arg1 |
0x13 |
JGT |
Jump if dist > arg1. |
dist, arg1 |
0x14 |
JGE |
Jump if dist >= arg1. |
dist, arg1 |
0x15 |
JEQ |
Jump if dist == arg1. |
dist, arg1 |
0x16 |
JNE |
Jump if dist != arg1. |
dist, arg1 |
0x17 |
CALL |
Call subroutine at address arg1. |
dist, arg1 |
0x18 |
RET |
Return from subroutine. | - |
0x19 |
FORK |
Create a new agent (replication). | - |
0x1A |
YIELD |
Yield CPU for the next tick. | - |
0x1B |
ZEROS |
Zero out register dist. |
dist |
0x1C |
ROL |
Rotate Left. | dist, arg1, arg2 |
0x1D |
ROR |
Rotate Right. | dist, arg1, arg2 enum Dna { ... } |
0x1E |
SHL |
Shift Left. | dist, arg1, arg2 |
0x1E -> 0x1F |
SHR |
Shift Right. | dist, arg1, arg2 |
0x20 |
REV |
Reverse bits. | dist, arg1 |
0x21 |
POPCNT |
Population Count (popcount). | dist, arg1 |
0x22 |
NOP |
No Operation. | - |
The VMAmem struct defines the memory layout for an agent.
genome: A vector of 32-bit integers representing the compiled bytecode.tape: A vector of 32-bit integers representing the mutable data tape.
The VMACache struct defines the CPU state for an agent.
regs: An array of 32 general-purpose registers.Dna: A 64-byte aligned structure to ensure cache line efficiency.
The mutate method implements a genetic algorithm approach to evolution.
- Random Insertion: Adds new codons (4-byte instructions).
- Deletion: Removes codons.
- Swapping: Swaps codons at random positions.
- Jitter: Randomly modifies specific fields of a codon (opcode, dist, arg1, custom).
- Insertion: Inserts a new codon at a random position.
- Initialization: Sets up agents with a "Luca DNA"
Iterate steps (3-6) till success.
- Competition: Agents compete for resources (CPU time and memory).
- Evaluation: Agents are evaluated based on error (difference between expected and actual output).
- Selection: The agent with the lowest error is copied to the other agent.
- Evolution: Agents mutate over time.
Please be aware that this code can execute theorically anything possbile, and the only question is when! So keep that in mind when your programming simulations, these organism will always find exploits in microseconds if you made any oversight in your logic. I do not claim responsibility for anything that you machine executes base off this source code!