Hey 👋, Today's article is challenging. It was a challenge to write, and I believe is a challenge to read. Therefore, take it easy. Yet, it's one of the articles I enjoyed the most writing. I didn't just researched a concept, instead, I had to solve a problem very similar to the one CPUs face. It was fun and interesting. I hope you enjoy it just half of how much I enjoyed it. I would consider that a success. As always, don't hesitate to let me know what you think by replying to the email. Have fun!  Feynman’s File ClerkIn a previous article, we saw how Richard Feynman compared computers to a file clerk. By making the clerk dumber and dumber, it looked more and more like a computer. Yet, the clerk was still able to do many things that computers don’t. Note: You might still understand the idea behind this article, but to better understand Feynman’s view of how computers work, I recommend reading the previous article. In this article, I’d like to close the gap in how computers compare to file clerks. Binary ClerkComputers work in binary, we know that. Let’s hire a file clerk that can only read 0s and 1s and ask him to calculate the commissions for California. Specifically, let’s convert two of the cards we used in the previous article into binary. The data card with the salesperson details: And one instruction card: Data CardHow can we convert the data to binary? For example, how can we convert “California” to binary? California represents one of the company’s locations. Therefore, we can for example enumerate the locations and use the order in binary:  Alabama
 Alaska
 Arizona
 Arkansas
 California
 …
Therefore, “California” corresponds to the number 5, which is 101 in binary . Now the sales: $30.000. Let’s assume that we always have sales in thousands of dollars. We accept the loss of precision. Therefore, the sales are 30 (thousand $), which is 11110 in binary. For the commission, we also assume that it’s always in percentage. So, 5% gets converted to 101. Now the values are in binary. But the clerk only reads 0s and 1s, which means he can’t understand “Location” or “Sales.” Those are attributes of the salesperson. Let’s enumerate them:  Location (1 in binary)
 Sales (10 in binary)
 Commission (11 in binary)
If we use the binary value of the enumeration, we have the following: HelpersThe file clerk used a piece of paper to write down numbers because he had no memory. We are going to change the piece of paper a little bit: The paper has six distinct parts. Four are enumerated in binary which we call “Registers”: Register 00 (R00), R01, R10 and R11. Then we have one I called “Pad.” Which the clerk uses to write down constants used in calculations, such as in if location is California . "California" is a constant. Lastly, we have a space to put the current card. Instructions CardThis is a little bit trickier and longer, so bear with me., The proposed way is not the only way to translate the instructions to binary. There are many other ways. I divide the “if” statement into more basic instructions that we can then easily convert to binary.  Reading a property of the salesperson (Location).
 Using a constant: “California”. Or writing a value in the Pad.
 Reading a value in the card.
 Compare two values (property and constant).
 Jump depending on a value.
 Jump to another instruction.
Basic InstructionsThe basic instructions we want to convert are: If the location is “California”
Go to Instruction 33
Otherwise go to 30
"IF" StatementLet’s translate the first part into the basic instructions I introduced earlier: Write “California” (101) in Pad
Write Pad in Register 00
Write “Location” (1) in Pad
Write Pad in Register 01
...
At this point, we have the value of “California” in Register 00 and “Location” in R01. Yet, we need the value of the “Location” property in the card. We'll use another instruction here. Use the value in Register 01 as the property of the Card. Then write the value of the property in Register 01
This instruction uses the value in R01 as the property to read in the Card. This means that by the end of the last instructions, we have the value of the “Location” in R01. Compare values How can the clerk compare the value in R00 and the current value in R01? By subtracting both values and checking the result. If both values are the same, then the subtraction is always zero. Subtract Register 00  Register 01, put the result in Register 00.
The value of Register 00 will be 0 if the salesperson's location matches “California”. Jump InstructionsUp until here, we converted to basic instructions the first line in the instruction: `If the location is “California”`. The value of R00 is 0 when the condition is true, false for any other value in R00. Now we need to convert the last two instructions: Go to Instruction 33 (if true)
Otherwise go to 30 (otherwise)
For the first one, we do the following: Write 33 in Pad (where we want to jump in the first instructions)
Write Pad in Register 10
If Register 00 is zero, jump to the instruction in R10
If R00 is 0, then the clerk jumps to the instruction in R10, which is 33—Ignoring the next lines. Now the last instruction Otherwise go to 30 . Write 30 in Pad
Write Pad in Register 10
Jump to value R10
If we put the two jumping instructions together it reads: Write 33 in Pad (where we want to jump in the first instructions)
Write Pad in Register 10
If Register 00 is zero, jump to the instruction in R10
Write 30 in Pad
Write Pad in Register 10
Jump to value R10
Basic InstructionsFinally, let’s put all the basic instructions together: Write “California” in Pad
Write Pad value in Register 00
Write “Location” in Pad
Write Pad value in Register 01
Use the value in Register 01 as the property of the Card. Then write the value of the property in Register 01
Compute Register 00  Register 01, put the result in Register 00.
Write 33 in Pad
Write Pad in Register 10
If Register 00 is zero, jump to the instruction in R10
Write 30 in Pad
Write Pad in Register 10
Jump to value R10
Pseudo AssemblyLet me now rewrite the basic instructions in some kind of pseudocode: Pad = “California”
R00 = Pad
Pad = “Location”
R01 = Pad
R01 = Card[R01] # This reads the property that matches R01 (location) from the Card in the paper.
R00 = R00  R01
Pad = 33
R10 = Pad
JMPZ R00, R10 # Jump to R10, if value in R00 is zero
Pad = 30
R10 = Pad
JMP, R10 # Jump always (if we jumped earlier, we would not get here)
Let’s write now the values in binary: Pad = 101 # “California”
R00 = Pad
Pad = 1 # “Location”
R01 = Pad
R01 = Card[R01]
R00 = R00  R01
Pad = 100001 # 33
R10 = Pad
JMPZ R00, R10
Pad = 11110 # 30
R10 = Pad
JMP, R10
We translated each basic instruction description into some kind of assembly language. Now, we are ready to translate the assembly to binary. Yet, for this, we need some kind of standard. SpecificationSome instructions need one argument, such as “JMP, R10”, while others need two arguments like Subtract. How does the clerk know when to expect one argument or two? He doesn’t know. Therefore, we are always going to expect two arguments, and we are going to standardize all the instructions to eight digits: “C I I I S S T T”. Constant CodeWhen the first digit "C" is 1: Remember that we also need to handle values like “California” (101) or “30” (11110). So how does the clerk know what is a value or an instruction? The first digit: C, helps the clerk to differentiate them. If it starts with a 1, then it’s a constant. The clerk then writes it down on the Pad. In our assembly code, the line was Pad = … Therefore, “California” is “10000101,” and “30” is “10011110”. Instruction CodeWhen the first value is 0, it’s an instruction. The next three digits tell which it is: “I I I”.  000: Write Pad in Register
 001: Write property in Register
 010: Subtract
 011: Jump if zero
 100: Jump
Source and TargetThe next two digits: “S S,” represent a register. Which we call “Source.” And the last two: “T T,” mean another one we call “Target.” They might have slightly different meanings depending on the instruction. For example: “Write Pad in Register 01” or in assembly `R00 = Pad` is written in binary as: Another example: Subtract Register 00  Register 01, put the result in Register 00. or R00 = R00  R01 . Clerk CodeIf we translate the pseudoassembly to binary, we get the following list of instructions: 10000101 # Pad = California
00000000 # R00 = Pad
10000001 # Pad = Location
00000001 # R01 = Pad
00010101 # R01 = Card[R01]
00100001 # R00 = R00  R01
10100001 # Pad = 33
00000010 # R10 = Pad
00110010 # JMPZ R00, R10
10011110 # Pad = 30
00000010 # R10 = Pad
11000010 # JMP, R10
Remember that this represents the following card in binary: Maybe not what you expected. This code is similar to the Machine Code in our computers. RulesWe needed a lot of “rules” that we had to explain to our clerk to be able to use only binary values. This is the tradeoff for a clerk that can only read 0s and 1s—for example, the first digit in the code to differentiate constants and instructions. Yet, this is still some kind of generalpurpose clerk. Given different cards and different codes, it could compute all sorts of calculations. Hardwired rules are also present in CPUs and computers. They are metarules, rules governing how to write and interpret other rules (aka instructions, aka code). In the end, we accomplished the target, our clerk understands only 0s and 1s. Knowing 0s and 1s is not much different from noticing voltage or no voltage. Just like computers do.
If you like this post, consider sharing it with your friends on twitter or forwarding this email to them 🙈 Don't hesitate to reach out to me if you have any questions or see an error. I highly appreciate it. And thanks to Michal for reviewing this article 🙏
