Ok, so I know that the alphabet of computers consists of only two symbols, or states: zero and one.
I also seem to understand how computers count beyond one even though they don’t have symbols for anything above one.
What I do NOT understand is how a computer knows* that a particular string of ones and zeros refers to a number, or a letter, or a pixel, or an RGB color, and all the other types of data that computers are able to render.
*EDIT: A lot of you guys hang up on the word “know”, emphasing that a computer does not know anything. Of course, I do not attribute any real awareness or understanding to a computer. I’m using the verb “know” only figuratively, folks ;).
I think that somewhere under the hood there must be a physical element–like a table, a maze, a system of levers, a punchcard, etc.–that breaks up the single, continuous stream of ones and zeros into rivulets and routes them into–for lack of a better word–different tunnels? One for letters, another for numbers, yet another for pixels, and so on?
I can’t make do with just the information that computers speak in ones and zeros because it’s like dumbing down the process human communication to the mere fact of relying on an alphabet.
In: 264
I see a lot of comments at the more abstract end, looking at software and compilation, so I’ll take a crack from the other end.
Let’s start near the beginning: we have an electrical device known as a “transistor”, which in very simplified terms can be used as an electronically controlled switch, where we have the two ends we want to connected as well as a control input to determine if the ends are connected. We could say that a high voltage causes electricity to flow from end to end while a low one causes the ends to be unconnected. This idea of a switch allows us to actually perform logic operations based on high and low voltages (which we can assign the mathematical values of 1 and 0) when we arrange transistors in a certain way: AND, OR, NOT, XOR, NAND, NOR, XNOR. We call these arrangements “logic gates”, and this serves as a level of abstraction that we have built on top of individual transistors. For example, an AND gate has two inputs, and when both inputs are 1, it outputs a 1, and otherwise outputs a 0 (a la logical AND). This leads us to binary, representation of numbers where each digit can have two different values, 1 or 0. It works just like how we represent base-10 numbers in daily life where each digit can be from 0-9 and represents a power of 10. In binary, each digit can be 1 or 0 and represents a power of 2. By associating a bunch of high/low voltages together, we can represent a number electronically.
With the power of Boolean logic that deals with how math works with where values can be 1 or 0, or “true” and “false”, we can start to produce more and more complex logic equations and implement them by connecting a bunch of logic gates together. We can thus hook together a bunch of gates to do cool stuff, like perform addition. For instance we can represent the addition of two bits X and Y as X XOR Y. But oops, what if we try 1+1? 2 can’t exist in a single digit, so we could have a second output to represent this info known as a carry, which happens when X AND Y. Hooray, we’ve created what is known as a “half adder”! Now if we did multi-digit addition, we could pass that carry onto the next place in addition, and have different kind of adder called a “full adder” that can take the carry of another adder and use it as a 3rd input. All together we can create an adder that can add a group of bits to another one, and thus we have designed a math-performing machine 🙂
A CPU is ultimately made of these logic-performing building blocks that operate off of high/low voltage values which can be grouped together to form numbers (represented in binary) and work off of them.
The other comments covered a good deal of what happens above this at a software level. What software ultimately is a bunch of binary fed into the CPU (or GPU or other computing element). This binary is a sequence of numbers in a format that the CPU is logically designed to recognize and work off of: perhaps the CPU looks at the first 8-bits (aka a byte) and sees that it is the number 13. Perhaps the CPU designer decided that seeing 13 means that the CPU multiplies two values from some form of storage. That number 13 is “decoded” via logic circuits that ultimately lead to pulling values from storage, passing them to more logic circuits that perform multiplication. This format for what certain values mean to a CPU is known as an instruction set architecture (ISA), and serves as a contract between hardware and software. x86/x86_64 and various generations of ARM are examples of ISAs. For example, we see several x86_64 CPUs from Intel and AMD, they might all be implemented differently with different arrangements of logic circuits and implementations of transistors, but they’re still designed to interpret software the same way via the ISA, so code written for x86_64 should be runnable on whatever implements it.
This is an extremely simplified look at how CPUs do what they do, but hopefully it sheds some light on “how” we cross between this world of software and hardware, and what this information means to a computer. Ultimately, it’s all just numbers with special meanings attached and clever use of electronics such as transistors giving us an avenue to perform mathematical operations with electricity. Sorry if it’s a bit rambly; it’s very late where I am and I need to sleep, but I couldn’t help but get excited about this topic.
Latest Answers