4 ms·
Show HN: CPU simulator in 60 lines of code
- mungoman2 11y agoVery nice! Shows that it's possible to do something concise while still remain readability and educational value. My mind was absolutely blown when I first realized that the function of a CPU is pretty much to read tokens from a stream and perform an action for each. - no magic!
- jarcane 11y agoFor me the fun realization was when I cottoned on how nicely instruction microcode lines up as a concept with stored functions in a language with first class functions. Your instruction look up becomes your execution step in one go: https://github.com/jarcane/MicroMini/blob/master/main.rkt https://github.com/jarcane/MicroMini/blob/master/main.rkt
- lfowles 11y ago> My mind was absolutely blown when I first realized that the function of a CPU is pretty much to read tokens from a stream and perform an action for each. - no magic! The magic is mostly in the pipelining bit :)
- cantrevealname 11y ago> My mind was absolutely blown when I first realized that the function of a CPU is pretty much to read tokens from a stream and perform an action for each. My "aha!" moment when I first learned about CPUs was the program counter, or if you're an Intel guy, you'd call it the instruction pointer. The PC might seem obvious, but if you think about it for a moment, you'll realize that someone had to have invented it. It's not totally obvious. And as far as I can tell, the inventor is unknown. Note also that the featured program does not have a PC, so there are things it can't do that a normal CPU can do.
- rdc12 11y agoAnd if you look at computers based on drum memory, then you probably didn't have a PC, the optimal place for the next instruction then wasn't the next address, but instead how far the drum rotated during execution, at least in some of those machines the next instruction was encoded in the current instruction. Having RAM seems to be important to having a PC, that works well.
- oleks 11y agoLooks quite elegant :-) You should probably use else-if instead of ifs though, otherwise it is (immediately) complicated to e.g. count the number of instructions you execute.
- rootlocus 11y agoI don't get it. How does using else-if make it less complicated to count the number of instructions?
- hartator 11y agoBecause it will force only to execute one of the conditional branch. https://github.com/wkoszek/cpu60/blob/master/cpu60.c https://github.com/wkoszek/cpu60/blob/master/cpu60.c might execute several. (It may be on purpose though.)
- mtdewcmu 11y agoIt won't execute more than one, because only one can match. The other sscanfs will all fail. I agree it would make sense to stop trying patterns once one has matched, though. Personally, my inclination would be to rewrite the loop to tighten it up. But maybe the point was to show how quickly and dirtily one can do this... it definitely looks quick and dirty.
- wkoszek 11y agoQuick, dirty and primitive was my primary motivation for this exercise :-)
- rootlocus 11y agoHow would you rewrite it to "tighten it up"?
- mtdewcmu 11y agoI would make that series of if-statements more obviously deterministic, for starters. One way of accomplishing that would be a bunch of nested if-else blocks. However, that would be ugly. I'd prefer something like continue statements -- which would necessitate redesigning the loop to avoid bypassing the code at the bottom. Either way, the way this currently gives the appearance of being possibly nondeterministic makes me uncomfortable... and besides, executing those extra conditionals wastes CPU cycles.
- scottmwinters 11y agoneat project. I like it.
- hobbyist 11y agoThere are no cmp, branch instructions. How is this turing complete?
- Alupis 11y ago> There are no cmp, branch instructions. How is this turing complete? I see no claim for it to be?
- Rebellos 11y agoCPU by common sense should be Turing complete.
- pdq 11y agoThis is a partial ALU and Register File. It is not a CPU.
- wyldfire 11y agoAll you need is logical AND, logical OR, and logical NOT. I suppose they could compose them from the operations there.
- canacrypto 11y agoHe could have saved another 10 lines by dropping the braces around the if statements :P
- wkoszek 11y agoThe idea was to make it small, but not too "compressed". And I always like having braces everywhere for clarity.
- JustSomeNobody 11y agoI, too, prefer braces for clarity.
- kelvin0 11y agoThats probably 10 lines of lisp ...
- DiabloD3 11y ago... and one line of perl.
- zwegner 11y agoSmall security hole in this: since i0/i1/i2 are signed ints, i0 % 8 etc can be negative, and thus allow writing in the 7 bytes before r[], quite possibly leading to a stack smashing attack. So you probably don't want to run this in production :)
- wkoszek 11y agoYou're right: I didn't design it to be run with UID 0. However I fixed the issue and gave you the credit: https://github.com/wkoszek/cpu60/commit/672711f3e06bba424b98263655ca923eaf587a1b https://github.com/wkoszek/cpu60/commit/672711f3e06bba424b98...
- dvt 11y agoGreat work! Add some branching and it's Turing-complete :)
- kragen 11y agoI think this is more like an ALU simulator (plus registers) than a CPU simulator. There are no jumps, either conditional or unconditional, because it's reading the instruction stream from standard input. https://github.com/kragen/calculusvaporis/blob/master/cavosim.c https://github.com/kragen/calculusvaporis/blob/master/cavosi... is a CPU simulator in 70 lines of code, but it's perhaps a bit impractical; you have to synthesize addition from subtraction, for example, and AND and OR from NAND. The design objective of Calculus Vaporis, however, is to use as few logic gates as possible, rather than to be as simple as possible in C. http://canonical.org/~kragen/sw/aspmisc/brainfuck.c http://canonical.org/~kragen/sw/aspmisc/brainfuck.c is a 66-line BF interpreter, but BF is not a very good CPU design, in that it doesn't support subroutines.
- jhallenworld 11y agoWell, use fseek to implement jumps (use fixed length lines or "assemble" the source file so that has byte offsets for branch targets).