If you’re nerdy like me, you might be into low level programming, which means fiddling with instructions. Unfortunately, the complexity easily spirals out of control, hence developing in a simple instruction-set is a great way to learn how a CPU works, and being able to write tiny applications that get things done.
An excellent example of such a language is Little-Man-Computer. It features a CPU with 1 register, 1 input, 1 output, 1 flag and 100 memory slots. It is minimalistic to the point that it lacks instructions for multiplication and division.
Specification of the instruction set:
[tr][td]1xx[/td][td]ADD xx[/td][td]ADD[/td][td]Add the value stored in mailbox xx to whatever value is currently on the accumulator.[/td][/tr]
[tr][td]2xx[/td][td]SUB xx[/td][td]SUBTRACT[/td][td]Subtract the value stored in mailbox xx from whatever value is currently on the accumulator.[/td][/tr]
[tr][td]3xx[/td][td]STA xx[/td][td]STORE[/td][td]Store the contents of the accumulator in mailbox xx.[/td][/tr]
[tr][td]5xx[/td][td]LDA xx[/td][td]LOAD[/td][td]Load the value from mailbox xx and enter it in the accumulator.[/td][/tr]
[tr][td]6xx[/td][td]BRA xx[/td][td]BRANCH (unconditional)[/td][td]Set the program counter to the given address (value xx).[/td][/tr]
[tr][td]7xx[/td][td]BRZ xx[/td][td]BRANCH IF ZERO (conditional)[/td][td]If the accumulator contains the value 0, set the program counter to the value xx.[/td][/tr]
[tr][td]8xx[/td][td]BRP xx[/td][td]BRANCH IF POSITIVE (conditional)[/td][td]If the accumulator is 0 or positive, set the program counter to the value xx.[/td][/tr]
[tr][td]901[/td][td]INP[/td][td]INPUT[/td][td]Go to the INBOX, fetch the value from the user, and put it in the accumulator[/td][/tr]
[tr][td]902[/td][td]OUT[/td][td]OUTPUT[/td][td]Copy the value from the accumulator to the OUTBOX.[/td][/tr]
[tr][td]000[/td][td]HLT[/td][td]HALT[/td][td]Stop working.[/td][/tr]
[tr][td]xxx[/td][td]n/a[/td][td]DATA[/td][td]Instruction which simply loads the value into the next available mailbox.[/td][/tr]
Simple program: (adds 13 and 14)
[tr][td]address[/td][td]instr[/td][td]code[/td][td]description[/td][/tr][tr][td]#0[/td][td]104[/td][td]ADD 4[/td][td]add value of address #4 to register[/td][/tr][tr][td]#1[/td][td]105[/td][td]ADD 5[/td][td]add value of address #5 to register[/td][/tr][tr][td]#2[/td][td]902[/td][td]OUT[/td][td]write register to output[/td][/tr][tr][td]#3[/td][td]0[/td][td]HLT[/td][td]halt execution of program[/td][/tr][tr][td]#4[/td][td]13[/td][td]DATA: 13[/td][td]store the value 13[/td][/tr][tr][td]#5[/td][td]14[/td][td]DATA: 14[/td][td]store the value 14[/td][/tr]
Obviously you can make (conditional) jumps, which allows you to make loops.
I created an applet which simulates this CPU, for you guys to play around. It really gets fun, once you get the hang of it.
[applet archive=lmc_ui.jar class=eden.emulator.lmc.LmcApplet width=512 height=256]
First thing you can do is trying to read two numbers from INPUT, subtract them, and write them to the OUTPUT. Next you can write code that is able to multiply two numbers. Maybe you feel naughty and try to raise N to the power of M. You’ll need to use self-modifying code, seriously.