Cover of the summary of “Code”

Book summary “Code”: summary

Charles Petzold

3,830 words · 22 min read

You use computers every day without knowing how they actually work beneath the glass and plastic. Flashlights, Braille, and telegraphs rely on simple binary codes and electrical circuits to communicate information across physical spaces.

Summary text

3,830 words · 22 min read

Introduction

You use computers every day without knowing how they actually work beneath the glass and plastic. Flashlights, Braille, and telegraphs rely on simple binary codes and electrical circuits to communicate information across physical spaces. The inner workings of these machines often seem like magic, leaving you dependent on devices you cannot repair or truly understand.

Charles Petzold demystifies computer hardware and software from the ground up in Code. You can understand how computers work by tracing the evolution of codes, electrical circuits, logic gates, and microprocessors. The book moves systematically through logic gates, number systems, binary arithmetic, memory, CPU architecture, operating systems, and high-level languages.

You will find answers to several core questions as you read:

  • How do simple switches create logical thought?
  • Why do computers use binary numbers instead of decimal numbers?
  • How do bits of electricity become stored memory?
  • What happens inside a microprocessor when it executes a program?

1. Codes and Electrical Circuits

Simple binary systems and electrical circuits form the foundational physical medium for transmitting information across distances.

Communication Codes

You can convey complex language using simple binary systems like flashlight blinks. Morse code assigns short blinks for dots and long blinks for dashes, drastically reducing the total number of blinks needed. Sending the sentence 'How are you?' requires 131 blinks in a naive counting system, but only 32 blinks using Morse code. A normal human speaker achieves about 100 words per minute, while a special flashlight sending speed reaches 5 to 10 words per minute.

When you operate a signaling light, you follow precise rules for the physical signals:

  • Turn the flashlight switch on and off quickly for a dot and somewhat longer for a dash.
  • Keep the length of a dash about three times that of a dot.
  • Leave an off period equal to about one dot between the dot and dash of a letter.
  • Separate letters in the same word by a pause equal to the length of a dash.
  • Separate words by an off period of about two dashes.

Louis Braille was blinded at age three by a tool in his father's harness shop and later refined Captain Charles Barbier's night writing system at the Royal Institution for Blind Youth in Paris. Louis Braille was born in 1809 in Coupvray, located 25 miles east of Paris, and was sent to Paris at 10 years old before he died in 1852. Braille adapts a binary six-dot cell structure to represent characters tactilely while incorporating shift and escape codes for efficiency. A two-by-three cell where each dot is either flat or raised yields 64 unique codes, while an eight-dot Braille system yields 256 unique codes.

Electricity Basics

Electricity flows through a continuous circular path of conductors driven by voltage and regulated by resistance according to Ohm's law. An electrical circuit requires a continuous closed loop for electrons to move from atom to atom. Standard cylindrical flashlight batteries generate 1.5 volts, which acts as the potential for doing work. One amp of current measures 6 quintillion electrons per second passing a point. A typical flashlight incandescent bulb has 4 ohms of resistance, drawing 0.75 ampere or 750 milliamperes of current and producing 2.25 watts of power.

Connecting a battery's terminals with a short piece of copper wire creates a short circuit with very high current and heat. Electrical communication systems can be expanded around corners and over long distances by using shared circuit commons and earth grounds. You can reduce wire expenses by 25 percent by using a common return path. Connecting an 8-foot copper pole buried in the backyard allows the Earth to act as an electron source and repository, reducing the required number of wires between remote stations. The Earth has a diameter of 7900 miles, and a grounding pole 8 feet long and 0.5 inches in diameter provides 150 square inches of contact with the earth. Wire resistance varies by gauge, measuring 10 ohms per 1000 feet for 20-gauge speaker wire and 1 ohm per 1000 feet for 10-gauge wire according to American Wire Gauge standards.

2. Logic and Switches

Electrical switches wired in series and parallel physically execute the Boolean algebra operations of AND, OR, and negation.

George Boole revolutionized mathematics by creating an abstract algebra that divorced operands from numbers, applying them instead to classes or sets. In Boolean algebra, operands represent classes of items rather than numbers. Operators like plus and multiplication represent union and intersection of classes rather than traditional arithmetic. Boole used classes of cats categorized by gender, color, and neutered status to demonstrate algebraic operations without numbers. George Boole lived from 1815 until 1864, dying at age 49. He published The Mathematical Analysis of Logic in 1847, was appointed Professor of Mathematics at Queen's College, Cork in 1849, and published An Investigation of the Laws of Thought in 1854.

Boolean Algebra

Relays and Logic Gates

When two switches are wired one right after the other in series, current flows and the lightbulb turns on only if both the left switch and the right switch are closed. You can build this circuit directly:

  • Connect a battery, a lightbulb, and two switches one right after the other in a single path.
  • Close both switches simultaneously to allow current to flow and light the bulb.

When two switches are wired in parallel, current flows and the lightbulb turns on if either the top switch, the bottom switch, or both switches are closed. You can configure this alternate arrangement:

  • Connect two switches and a lightbulb such that current has alternative parallel paths from the power source.
  • Close either the top switch or the bottom switch to light the bulb.

A relay is an electromechanical device that uses an incoming electrical signal to control a switch for an outgoing current, acting as a repeater or amplifier. Because electrical resistance in long wires weakens signals, a relay uses an electromagnet triggered by a weak incoming current to pull down a metal lever that connects a stronger battery to an outgoing wire. Claude Elwood Shannon demonstrated that relays can perform Boolean operations during his time at M.I.T. Claude Elwood Shannon lived from 1916 to 2001 and wrote his master's thesis in 1938 on relay and switching circuits. The word NAND was coined in 1958. By cascading relays in series or parallel, engineers create logic gates that process binary values of 0 and 1 without human fingers flipping switches.

3. Number Systems and Binary Representation

Positional number systems use powers of two and base conversions to represent quantities compactly using bits.

Unlike non-positional systems such as Roman numerals, the Hindu-Arabic system relies on position. A single symbol like 1 changes its value drastically depending on whether it represents a hundred or a million, made possible by the use of zero as a placeholder.

The number of letters in the Latin alphabet is 32 in octal, which equals 26 in decimal.

An octal or base-eight number system is the natural consequence of counting using four fingers on each hand, demonstrating that decimal systems are purely arbitrary. If humans had four fingers like cartoon characters, counting would naturally skip numbers containing 8 or 9. The number after 7 in octal is 10, which represents eight in decimal.

Binary, or base-two numbering, uses only the digits 0 and 1, making it exceptionally brief in digits while growing in length rapidly. Dolphins with two flippers would naturally use a base-two system. In binary, the next number after 1 is 10. Positions in a binary number correspond to powers of two, allowing arithmetic to be performed using extremely simple rules.

To convert a two-digit octal number beginning with 1 to decimal, add 8 to the second digit. To convert a two-digit octal number beginning with another digit, multiply the first digit by 8 and add the second digit.

Binary and Octal

Octal numbers serve as a concise way to express long binary numbers because every three binary digits correspond to exactly one octal digit. Because eight is a power of two, grouping binary digits into sets of three allows direct translation into octal digits, reducing the length of large binary strings.

The binary number for twelve million, 101101110001101100000000, breaks down into groups of three to become 55615400 in octal.

To convert a binary number, you follow specific mechanical procedures:

  • Separate a binary number into groups of three starting from the right.
  • Convert each group of three binary digits into its corresponding octal digit.
  • Place binary digits into an eight-box template, multiply each by its corresponding power of two, and sum them to convert to decimal.
  • To convert decimal to binary up to 255, divide the number successively by powers of two from 128 downward, record quotients as binary digits.

Decoders and Encoders

Electronic circuits such as decoders and encoders use logic gates to translate between multi-digit binary codes and specific positional outputs. A 3-to-8 decoder uses switches for binary inputs and three-input AND gates combined with inverters to light up one of eight output bulbs.

Closing the first switch to represent the binary number 100 activates the AND gate associated with the octal number 4, lighting up the corresponding bulb.

Conversely, an 8-to-3 encoder uses an 8-position switch and OR gates to generate a binary representation.

4. Character Encoding and Binary Addition

Standardized character sets and logic gate combinations enable computers to encode text and perform binary arithmetic.

Character Codes

American Standard Code for Information Interchange is a 7-bit character encoding standard established in 1967 that defines 128 codes for English text, graphics, and control functions. ASCII uses 7 bits to represent 128 codes ranging from 00h to 7Fh, avoiding the ambiguity of shift codes by dedicating distinct codes to uppercase letters, lowercase letters, numbers, punctuation marks, and 33 non-printing control characters.

The text string 'Hello, you!' is represented in ASCII using specific hexadecimal codes such as 48 for H and 2C for a comma.

Unicode expanded character encoding to support global languages and symbols, while UTF-8 provided a backward-compatible variable-byte transformation format. Unicode evolved from a 16-bit code into a 21-bit code ranging up to U+10FFFF to support over 1 million characters, including non-Latin scripts and emojis. UTF-8 encodes these values using 1 to 4 bytes while maintaining backward compatibility with 7-bit ASCII.

A web-hosting provider email error displayed 'We’ve' because UTF-8 three-byte sequences for a right single quotation mark were misinterpreted as Windows-1252 characters.

Adders and Arithmetic

Combinations of basic logic gates construct an Exclusive OR gate, which is fundamental for generating the sum bit in binary addition. Adding two 1-bit numbers yields a sum bit and a carry bit. An Exclusive OR gate outputs 1 when either input is 1 but not both, effectively combining OR, NAND, and AND logic operations to produce the exact sum bit required.

Half adders and full adders encapsulate logic gates to perform column-by-column binary addition including carry bits. A half adder combines an XOR gate and an AND gate to add two bits into a sum and a carry out. A full adder connects two half adders and an OR gate to add three bits, incorporating a carry in from a previous column.

Building an 8-bit binary adding machine requires eight full adders chained together.

Computers perform subtraction without the messy mechanism of borrowing by converting the operation into the addition of a complement.

In decimal, subtraction can be simplified using the nines' complement, where subtracting a number from a string of nines avoids borrows. In binary, subtracting from a string of ones yields the ones' complement, which is achieved simply by inverting every bit. Adding 1 to the ones' complement produces the two's complement, allowing subtraction to be executed entirely through standard addition.

To subtract 176 from 253 in binary using the ones' complement method, the program inverts the bits of 176, adds it to 253, adds 1, and discards the overflow bit to arrive at 77.

You can execute complement arithmetic using these exact steps:

  • Invert every bit of the number to calculate the ones' complement.
  • Add 1 to the ones' complement to generate the two's complement.
  • Add the resulting two's complement number to the minuend using standard binary addition.
  • Discard any resulting carry out or overflow bit beyond the allocated byte size for positive results.

Using two's complement representation allows computers to store both positive and negative integers within a fixed bit width, while sign bits and overflow logic detect when results exceed valid ranges. In an 8-bit signed integer, the leftmost bit acts as a sign bit where 1 denotes negative and 0 denotes positive, giving a range from -128 to 127. If an addition or subtraction yields a result that exceeds this range, an overflow occurs. Hardware uses specific combinations of AND and NOR gates connected to the input and sum sign bits to light an overflow lamp when the result wraps incorrectly.

Adding 125 to 125 in 8-bit two's complement yields 11111010, which starts with a 1 and is falsely interpreted as -6, triggering a positive overflow condition.

5. Hardware Evolution and Storage

The transition from relays to transistors and integrated circuits enabled the construction of stable memory cells and flip-flops.

Hardware Progress

John Bardeen and Walter Brattain demonstrated the first transistor at Bell Labs on December 23, 1947, after wiring a germanium semiconductor and gold foil. Solid-state electronics replaced vacuum tubes with semiconductor materials to build smaller, cooler, and more reliable logic gates. Jack Kilby of Texas Instruments in July 1958 and Robert Noyce in January 1959 independently invented the integrated circuit, leading to a decade of patent disputes. Gordon Moore observed that transistors on a chip doubled every 18 months, a principle known as Moore's law.

Flip-Flops and RAM

An R-S flip-flop is a circuit built with feedback that can retain information and remember which input was most recently activated. A seesaw serves as an analog to a flip-flop, having two stable states and clearly showing which side was pushed down most recently.

  • Close the top switch to set Q to 1 and turn the light on, which stays on when the switch is opened.
  • Close the bottom switch to set Q to 0 and turn the light off, which stays off when the switch is opened.

A level-triggered D-type flip-flop stores a specific bit of data when the clock signal is at a high level. Cascading edge-triggered flip-flops with feedback creates a frequency divider and a binary counter.

  • Connect the output of an oscillator to the Clock input of an edge-triggered D-type flip-flop.
  • Connect the Q bar output back to the D input to form a frequency divider.
  • Chain multiple frequency dividers together to form a ripple counter that counts in binary.

Eight level-triggered D-type flip-flops can be consolidated to store an entire byte of data simultaneously.

  • Consolidate all Clock inputs of eight D-type flip-flops into one signal.
  • Apply an 8-bit value to inputs D0 through D7.
  • Send a 1 signal to the Clock input to transfer the entire 8-bit value to the Q outputs.

Combining multiple memory cells with decoders and selectors creates random-access memory arrays.

6. Central Processing Unit Architecture

Computers divide into memory, the central processing unit, and input/output peripherals. A computer program is a sequence of machine code instructions and data that you execute sequentially.

Microprocessors coordinate registers, data busses, arithmetic logic units, and control signals to fetch and execute instructions.

The ALU

The arithmetic logic unit performs 8-bit additions, subtractions with carry, and bitwise Boolean operations controlled by function signals. The ALU handles arithmetic operations via an Add/Subtract module utilizing ones' complement and carry bits, alongside a Logic module that executes bitwise AND, OR, and XOR operations.

  • Bitwise OR operations can convert ASCII uppercase text to lowercase by setting a specific bit to 1.
  • Bitwise AND operations with DFh can convert text to uppercase.

An ALU tracks operation results using status flags such as the Carry flag, Zero flag, and Sign flag to evaluate equality, magnitude, and positive or negative values. During operations like Compare, which is a subtraction whose result is discarded, status flags capture vital state information:

  • The Carry flag indicates relative magnitude.
  • The Zero flag indicates equality.
  • The Sign flag indicates whether a two's complement result is negative.

Finding text on a webpage relies heavily on the Compare operation to check character matches. The Intel 8080 implements 244 instruction codes and can address 64K of random-access memory using a 16-bit address.

Registers and Control Signals

Seven special 8-bit latches called registers store bytes within the CPU, with the accumulator playing the central role in ALU operations. The Intel 8080 microprocessor defines seven registers identified as A, B, C, D, E, H, and L. Register A is the accumulator, whose value is always the first input to the ALU, and whose location receives the ALU output. Registers H and L can be paired to form a 16-bit memory address for indirect addressing.

Using registers H and L set to 0008h to store the value 55h in memory via instruction code 36h demonstrates indirect addressing. An Intel 8080 program using instructions like 3Eh, C6h, 32h, CEh, and 76h adds 1388h and 09C4h and stores the resulting 16-bit sum.

Busses act as shared communication pathways that interconnect all major CPU components for data and memory addressing. An 8-bit data bus ferries bytes among memory, registers, and the ALU, while a separate 16-bit address bus supplies memory addresses from sources such as the program counter, instruction latches, or the HL register pair. Tri-state buffers ensure that only one component drives a value onto a bus at any given time.

Moving a value from memory at address 2044h into the accumulator relies on the 16-bit address bus and 8-bit data bus. Synchronized control signals direct hardware components through distinct machine cycles to fetch and execute instructions. Control signals coordinate the flow of data by enabling tri-state buffers and triggering latch clock inputs. Instructions execute through 2, 4, or 6 machine cycles depending on whether an instruction has 1, 2, or 3 bytes.

  • Address RAM with the program counter value and store the opcode byte from memory in Instruction Latch 1.
  • Increment the program counter using the incrementer-decrementer.
  • Fetch subsequent instruction bytes into Instruction Latch 2 or Instruction Latch 3.
  • Execute the instruction by enabling latches onto the busses and clocking the destination register, accumulator, or ALU.

7. Software, Languages, and the Internet

Conditional jump instructions allow a CPU to repeat code a specific number of times by combining registers as counters and checking ALU flags.

Alan Turing set out to solve the Entscheidungsproblem in 1936 at age 24 while studying at Cambridge University. The conditional jump is the defining feature that makes all digital computers functionally equivalent in processing power and defines Turing completeness.

To execute a loop a set number of times, a program uses a register as a counter that decrements with each iteration. An arithmetic operation triggers ALU flags, such as the Zero flag, allowing conditional jump instructions like JZ or JNZ to either break out of the loop or continue iterating.

  • Adding 200 bytes stored in memory starting at address 1000h by storing the running total in register B and the counter in register C.

The CALL instruction saves the memory address of the instruction that follows it onto a LIFO memory structure called the stack before jumping to a subroutine. The stack pointer register tracks the stack location, allowing the RET instruction to pop the return address back into the program counter.

Loops and Subroutines

Converting a byte like 5Bh into two ASCII characters using a Digit subroutine starting at address 1532h and a ToAscii subroutine at address 14F8h relies on these exact jump and stack mechanisms.

High-level programming languages allow programmers to write portable, algebraic code that is independent of specific computer hardware, using compilers or interpreters to generate machine instructions. Grace Murray Hopper created the A-0 compiler for UNIVAC in 1952 and coined the term compiler. Hopl.info listed 8,945 high-level languages at year-end 2021, compared to an estimated 1,000 in 1993.

Assembly language replaces obscure machine code bytes with English-like mnemonics, requiring a program called an assembler to translate them into executable machine code.

  • Create a text file with an assembly-language program using a text editor like ED.COM or Notepad.
  • Run the assembler program from the command line, passing the assembly file as an argument to generate a machine-code file.

A CP/M program named PROGRAM1.ASM uses statements like ORG, LXI, MVI, and DB, which the assembler ASM.COM converts into a 16-byte executable file named PROGRAM1.COM.

High-Level Languages and Networks

The IEEE Standard for Binary Floating-Point Arithmetic was established in 1985 within an 18-page specification document known as IEEE Std 754-1985. Single-precision numbers occupy 4 bytes, while double-precision floating-point numbers occupy 8 bytes or 64 bits.

Multiplying 55.2 and 27.8 in JavaScript yields 1534.5600000000002 instead of the exact mathematical result 1534.56 due to binary representation limits. Brendan Eich designed JavaScript at Netscape in 1995, and today nearly 98 percent of the top 10 million websites use JavaScript.

  • Open a plain-text editor like Notepad on Windows or TextEdit on macOS and ensure plain-text format with spell check disabled.
  • Type the HTML structure containing opening and closing html, head, title, body, and paragraph tags with a result ID.
  • Insert a script tag containing JavaScript code between the body tags.
  • Save the file with an html extension onto the desktop.
  • Double-click the saved file to load it into a web browser, and refresh the browser page after making modifications.

Packet switching divides data into smaller segments accompanied by headers to share connection lines efficiently and isolate transmission errors. ARPANET became operational in 1971 and established core internet concepts by splitting a 30,000-byte text file into 20 parts of 1,500 bytes each. Tim Berners-Lee invented the World Wide Web in 1989, using HTML tags and URLs to link documents via HTTP requests.

10 Key Ideas

  1. Simple binary systems and electrical circuits form the foundational physical medium for transmitting information across distances.
  2. Electrical switches wired in series and parallel physically execute the Boolean algebra operations of AND, OR, and negation.
  3. Positional number systems use powers of two and base conversions to represent quantities compactly using bits.
  4. Standardized character sets and logic gate combinations enable computers to encode text and perform binary arithmetic.
  5. The transition from relays to transistors and integrated circuits enabled the construction of stable memory cells and flip-flops.
  6. Microprocessors coordinate registers, data busses, arithmetic logic units, and control signals to fetch and execute instructions.
  7. Conditional jump instructions allow a CPU to repeat code a specific number of times by combining registers as counters and checking ALU flags.
  8. High-level programming languages allow programmers to write portable, algebraic code that is independent of specific computer hardware, using compilers or interpreters to generate machine instructions.
  9. Assembly language replaces obscure machine code bytes with English-like mnemonics, requiring a program called an assembler to translate them into executable machine code.
  10. Packet switching divides data into smaller segments accompanied by headers to share connection lines efficiently and isolate transmission errors.

A summary is an independent retelling, not the text of the book.

Cover of the summary of “The Last Whalers” 20 min read

The Last Whalers

Doug Bock Clark
Cover of the summary of “Confess” 21 min read

Confess

Rob Halford
Cover of the summary of “Toast” 17 min read

Toast

Nigel Slater
Cover of the summary of “Ace Voices” 24 min read

Ace Voices

Eris Young
Cover of the summary of “For Small Creatures Such as We” 17 min read
Cover of the summary of “Two Trees Make a Forest” 16 min read
Cover of the selected audiobook Choose a chapter The player is ready
0:00 0:00

Volume