The Little Man Computer
The Little Man Computer is a simple pen-and-paper computer that was developed by created by Dr. Stuart Madnick in 1965 to help educate people on basic computing and assembly programming.
It is recommended you complete the Know-how Computer and its exercises before doing this one.
Setup
Materials
- Piece of paper (grid paper is best, but anything works)
- Pen
- A calculator
Preparation
Note: If you don't want to make this yourself, download the PDF from Chris Staecker's Paper Computers #2: The Little Man Computer video, which you can find in the description.
The Little Man Computer consists of an inbox, an outbox, and a set of 100 mailboxes.
Turn your paper landscape and create a grid of 10x10, taking up about two thirds of the width of the page. Each of these boxes should be numbered 00 to 99, from top bottom, left to right. Split the last third of the page in half vertically, with the top half as the inbox, and the bottom half as the outbox.
Instructions
These instructions will take a little more work to learn, as they don't come with the ease of text to help with understanding.
Code | Instruction | Meaning |
---|---|---|
000 |
END |
Stop the execution of code and end the program. |
1XY |
ADD |
Add the contents of mailbox XY to the current value of your calculator. This replaces the calculator's value with the result. |
2XY |
SUB |
Subtract the contents of mailbox XY from the current value of your calculator. This replaces the calculator's value with the result. |
3XY |
STA |
Store the value of your calculator in mailbox XY . This replaces the current value at mailbox XY . |
5XY |
LDA |
Load the value of mailbox XY into the calculator. This replaces the current calculator value. |
6XY |
BRA : Branch |
Set the next instruction to be the one contained in mailbox XY . |
7XY |
BRZ : Branch If Zero (see note) |
If the calculator contains the value 0 (or 000 to be verbose), set the next instruction to be the one contained in mailbox XY . Else, continue. |
8XY |
BRP : Branch If Positive (see note) |
If the calculator contains a positive value (between 0 /000 and 999 inclusive), set the next instruction to be the one contained in mailbox XY . Else, continue. |
901 |
INP |
Move the next value found in the inbox in the calculator. This removes the value from the inbox. |
902 |
OUT |
Place the value found in the calculator in the outbox. |
Inbox and Outbox
The inbox and outbox can hold multiple values in what is called a stack, where the last number that was placed in it will be the first one out. Think of it like a deck of cards, where the cards are pulled off of the top when removed, and when new cards are added, they will be added on top of the deck.
Calculator
The calculator holds a single value between 0
/000
and 999
inclusive and can ADD
and SUB
. The calculator also has three indicators that are set by the last operation it has completed: negative, if the result is below 0
; zero, if the result was exactly 0
; and positive, for if the result is between 0
and 999
.
The calculator cannot handle numbers below 0
/000
, nor any numbers over 999
. When executing subtraction, if the result ends up being below 0 (underflow), then this will cause the calculator to throw a negative flag, which would cause 7XY
to succeed and 8XY
to fail.
Mailboxes
Each mailbox can contain a number between 0
/000
and 999
. The mailboxes can contain both data upon which we are operating, as well as instructions we are looking to execute. Keep this in mind, as it's possible for our instructions to encroach on our data, and the Little Man will get confused and just stop working if he gets instructions he can't understand.
Process
The Little Man executes this process repeatedly until he runs out of stuff to do (taken from Wikipedia):
- Check the Program Counter (your pen, in this instance) for the mailbox number that contains a program instruction (i.e. zero at the start of the program).
-
Fetch the instruction from the mailbox with that number. Each instruction contains two fields:
- An opcode (indicating the operation to perform) and
- the address field (indicating where to find the data to perform the operation on).
- Increment the Program Counter (pen) so that it contains the mailbox number of the next instruction.
- Decode the instruction. If the instruction utilises data stored in another mailbox, then use the address field to find the mailbox number for the data it will work on (e.g. 'get data from mailbox 42').
- Fetch the data (from the input, accumulator, or mailbox with the address determined in step 4).
- Execute the instruction based on the opcode given.
- Branch or store the result (in the output, accumulator, or mailbox with the address determined in step 4).
- Return to the Program Counter to repeat the cycle or halt.
Usage
Addition
Like in the Know-how Computer, we'll start with addition, but in this case it will be a little different. In this case, we just have an add command handy (1XY
), so how hard can it be? :)
First, we will add two numbers to the inbox to eventually get added together. Our result will be in the output, of course. We know that to add two things together, one of our values will need to already be in the calculator, and the other value will need to be found in a mailbox. So before we get to adding, we will need to do that:
- Move the next value from the inbox into the calculator.
- Store that value in mailbox 50 (this is not a significant number, any mailbox above 30 or so will be fine).
- Move the next value from the inbox into the calculator.
So now we have the two numbers in place, ready to be added. Once we have this sum, we can place it into the outbox.
- Add the number in mailbox 50 to the calculator, replacing the calculator's old value with the sum.
- Put the value in the calculator into the outbox.
Now we can convert this into instructions that the Little Man can understand. Assuming we have our two numbers we want to add in the inbox:
Mailbox | Instruction |
---|---|
00 | 901 |
01 | 350 |
02 | 901 |
03 | 150 |
04 | 902 |
05 | 000 |
Try this out with a few different numbers as inputs. Remember, the calculator can't handle numbers above 999.
Return The Largest Number
Again we'll start by putting two numbers into our inbox. The question is: how will we know which number to return? And how can we tell the Little Man to return one thing or another based on that condition? What if we reframed the question as: which of our branching tools could help us execute one sequence of code over another based on a condition?
We have two conditional branches: branch if (the value in the calculator is) zero, and branch if (the value in the calculator is) positive. If we know these are our only branching options, and that they are both dependent on mathematical operations in the calculator, this leaves us with only two instructions that could help us solve this problem: 1XY
and 2XY
; ADD
and SUB
.
If we try using ADD
, you will see that adding two numbers in either order results in no discernable difference: 100
+ 50
is the same as 50
+ 100
. So if we know this, then we are only left with the SUB
instruction. Playing with SUB
, we can see that the order definitely does matter. 100
- 50
(50
) does not equal the same as 50
- 100
(-50
).
So knowing that we will need to use SUB
leaves us with which branch we want to use: 7XY
or 8XY
; branch if zero, and branch if positive. If we look at the last example of 100
and 50
, we can see that one of the differences is positive and the other negative. This would lead to us using the branch if positive instruction after we perform our subtraction method.
Now that we know our tools, lets put this in plain English:
- Load one number from the inbox into the calculator.
- Store the number in our calculator into mailbox 50.
- Load the next number from the inbox into the calculator.
- Store the number in our calculator into mailbox 51.
- Subtract the number in mailbox 50 from the current value of the calculator (this number should be the same as is in mailbox 51).
- If the result is positive, return the number in mailbox 51.
- Else, return the number in mailbox 50.
Now we can translate this into code the Little Man can understand:
Mailbox | Instruction |
---|---|
00 | 901 |
01 | 350 |
02 | 901 |
03 | 351 |
04 | 250 |
05 | 809 |
06 | 550 |
07 | 902 |
08 | 000 |
09 | 551 |
10 | 902 |
11 | 000 |
Challenges
- Create a program that takes four numbers from the inbox and outputs them in reverse order.
- Create a program that adds all numbers in the inbox, ending with a zero, and outputs the final sum. For example, an inbox of
[13, 426, 301, 95, 0]
would result in835
. - Create a program that squares a number and outputs the product. The inbox number must be 31 or below.
- Create a program that divides the first number in the inbox by the second. The output will be the quotient followed by the remainder.
- Create a program that takes in numbers followed by operators and calculates the result of the sequence. These operators are
401
for add,402
for subtract, and400
for equals. For example, an inbox of[20, 402, 15, 401, 95, 400]
would output100
. - Update your last program to handle multiplication and floor division (return only the quotient with no remainder).
Solutions
Assuming we have four numbers in our inbox.
Mailbox | Instruction/Data |
---|---|
00 | 901 |
01 | 350 |
02 | 901 |
03 | 351 |
04 | 901 |
05 | 352 |
06 | 901 |
07 | 902 |
08 | 552 |
09 | 902 |
10 | 551 |
11 | 902 |
12 | 550 |
13 | 902 |
14 | 000 |
Assuming the last number in the inbox is a zero.
Mailbox | Instruction/Data | Data Note |
---|---|---|
00 | 901 |
|
01 | 705 |
|
02 | 108 |
|
03 | 308 |
|
04 | 600 |
|
05 | 508 |
|
06 | 902 |
|
07 | 000 |
|
08 | 000 |
Total |
Mailbox | Instruction/Data | Data Note |
---|---|---|
00 | 901 |
|
01 | 315 |
|
02 | 317 |
|
03 | 517 |
|
04 | 712 |
|
05 | 516 |
|
06 | 150 |
|
07 | 316 |
|
08 | 517 |
|
09 | 218 |
|
10 | 317 |
|
11 | 603 |
|
12 | 516 |
|
13 | 902 |
|
14 | 000 |
|
15 | 000 |
Number from inbox |
16 | 000 |
Total |
17 | 000 |
Times number has been added |
18 | 001 |
The first number in the inbox will be divided by the second.
Mailbox | Instruction/Data | Data Note |
---|---|---|
00 | 901 |
|
01 | 317 |
|
02 | 901 |
|
03 | 318 |
|
04 | 517 |
|
05 | 218 |
|
06 | 812 |
|
07 | 517 |
|
08 | 902 |
|
09 | 519 |
|
10 | 902 |
|
11 | 000 |
|
12 | 317 |
|
13 | 519 |
|
14 | 120 |
|
15 | 319 |
|
16 | 604 |
|
17 | 000 |
Number |
18 | 000 |
Divisor |
19 | 000 |
Quotient |
20 | 001 |
Mailbox | Instruction/Data | Instruction/Data Note |
---|---|---|
00 | 901 |
|
01 | 350 |
|
02 | 901 |
|
03 | 252 |
|
04 | 808 |
|
05 | 550 |
"Equals" |
06 | 902 |
|
07 | 000 |
|
08 | 715 |
|
09 | 901 |
"Subtract" |
10 | 351 |
|
11 | 550 |
|
12 | 251 |
|
13 | 350 |
|
14 | 602 |
|
15 | 901 |
"Add" |
16 | 150 |
|
17 | 350 |
|
18 | 602 |
|
... | ||
50 | 000 |
Total |
51 | 000 |
Temp |
52 | 401 |
To determine operator |
References
- https://en.wikipedia.org/wiki/Little_man_computer
- https://www.youtube.com/watch?v=t-mOfXhgfQY&lc=UgwXIu1pFzxIC7pJyLd4AaABAg.9Slg5diLl1j9Slgcj6WvW6
- Online LMC
Incoming Links
Last modified: 202401040446