Domande di Internet

How do computers turn binary information into your usual computer programme?

Bentornati ad un’altra favoloso edizione delle domande di cultura generale!

73 utenti della rete avevano questa curiosità: Spiegami: How do computers turn binary information into your usual computer programme?

I dont know anything at all about the inner workings of a computer. For example, how does it turn «electricity on/off in this part of the computer» into «this pixel on the screen should be this color»?

Ed ecco le risposte:

A CPU has two main components, the processing unit and the control unit. The processing unit can store small amounts of data, do basic math and number manipulations, and other sorts of calculations. The control unit does stuff like sending data between different parts of the CPU, controlling input/output to other parts of the computer, and implementing logic that approaches what we would call a program. CPUs also have a Bus, which is a bunch of wires that run in a parallel line that all the other components of the CPU attach to in order to transfer data from one part of the CPU to another. In the case of a 64-bit computer (which most modern computers are), that bus has 64 wires, meaning that it can move a binary number with at most 64 digits. The main effect this has is on the maximum size of a number (in either direction from 0, since binary can do negative numbers) that the computer can handle. CPUs also have internal mini-blocks of memory called registers, which can handle small amounts of data (in modern computers, 64 ones or zeroes per register). The x86_64 CPU architecture that’s used on most desktops has four general-purpose registers, named A, B, C, and D (there are technically four more general purpose registers, but they generally contain important information you only mess with if you know what you’re doing). The names get changed a bit depending on how much of the register you’re using. If you’re using the first byte of the register, it’s called AL (A lower), second byte is AH (A higher). If you’re using two bytes, it’s AX. Four bytes is EAX. 8 bytes (64 bits) is RAX.

Memory, also called RAM (which is different from storage space), is where your computer stores data it isn’t actively using, or hasn’t in the past few nanoseconds. Memory on modern computers is what’s called byte-addressable (a byte is 8 bits, or 8 ones and zeros, and is the basic unit of data in a computer) meaning that you can think of RAM as a really long straight road with a line of houses on one side, and each house has its own address, and each house can hold 8 bits. If you want a number larger than one byte, say a 4-byte number (also called a long), you would say “address 245 and the next three after it.” Among the data in memory is programs, the data used by those programs, and data being sent from the CPU to something else, like video information being sent to your GPU.

If you want to implement a program that adds two numbers together, you would need to write it in machine code (which is binary numbers that represent individual instructions like “move data from this spot to this other spot” or “add the numbers in these two spots and put the result in some other spot.” What we think of programming languages can be converted to assembly language (which is basically human-readable machine code) and then converted into machine code. Here’s a simple example of a program that adds two numbers from memory, in the format “MEMORY_ADDRESS: INSTRUCTION //COMMENT EXPLAINING”:

0: MOV AL, [3]   // Move data from memory address 3 to the AL register
1: MOV BL, [4]   // Move data from memory address 4 to the BL register
2: ADD AL, BL    // Add the contents of AL and BL together, and store the result in AL
3: DB 4          // Declare one byte of data, with a value of 4
4: DB 8          // Declare one byte of data, with a value of 8

In order to make that program actually happen, we need to convert it to machine code. As it happens, instructions like MOV and ADD have binary number representations that vary depend on what they’re doing. For example, there’s a binary number that means “MOVE X AMOUT OF DATA FROM MEMORY ADDRESS TO REGISTER. THE NEXT 4 BITS REPRESENT THE REGISTER NUMBER AND THE X NUMBER OF BYTES AFTER THAT REPRESENT THE MEMORY ADDRESS TO LOOK IN”. Those numbers are completely arbitrary and are chosen by the people that designed the CPU.

Each instruction is made up of a few smaller mini-instructions that don’t take parameters in the way that the instructions above do. From here, it’s important to know about the system clock, the instruction register, and the instruction pointer. The system clock doesn’t know what time it is, it’s just a peice of crystal that oscillates at a known frequency, generating what’s known as the clock signal. The pulses from the clock advance the steps of the mini-instructions in a similar way that a metronome advances the beat of a song. (as a side note, when you see a CPU listed as 3.2GHz, that means the clock pulses 3.2 billion times per second, or once every 0.3 nanoseconds). The instruction register is paired with a little counter that increments with each clock pulse. The instruction register is hardcoded (as in hardware programmed rather than software programmed) to have the binary representation of the current instruction (including the parameters) placed in side it, and to output the mini-instruction you need to do for that that instruction depending on the value of the counter. There are usually more than one mini-instructions per clock pulse, and usually with an IN or OUT part. If it’s OUT, it means that the contents of the component referred to is sending data out to the bus, and if its IN, it’s reading data from the bus. This is how data is transferred between components in the CPU. The instruction pointer is effectively just a normal register, but it contains the memory address of the current instruction.

In order to execute the first instruction of the example program above (MOV AL, [4]), these are the mini-instructions that would happen:

INSTRUCTION POINTER OUT - MEMORY ADDRESS IN. This tells the Instruction Pointer to output its contents (which is starting at zero) to the bus, and tells the RAM controller to open up memory the memory address that it reads from the bus (which is zero, from the instruction pointer).

MEMORY CONTENTS OUT - INSTRUCTION REGISTER IN - INSTRUCTION POINTER INCREMENT. This moves the contents of memory address 0 (which is the MOV instruction itself) to the instruction register so that the CPU actually knows what instruction to execute. This also increments the instruction pointer, so that next cycle it'll look at address 1 and execute that instruction. These two steps are the same for any instruction, since they're required in order to know what the instruction actually is.

INSTRUCTION REGISTER OUT - MEMORY ADDRESS IN. This outputs the contents of the instruction register (but only really the part of it that contains the memory address to be loaded, not the entire contents) to the RAM controller.

MEMORY CONTENTS OUT - A REGISTER IN. This moves the contents of memory at the address that was loaded to the A register.

At this point, the entire MOV instruction has been executed. The mini-instruction counter resets 0 zero, and the cycle begins again, loading and executing the next instruction in the program. Because the instruction has 4 mini-steps, each mini-step takes one clock cycle (0.3 nanoseconds), and there are only three instructions in the program (DB isn’t an instruction, it’s encoded as just data with an address in machinecode), that means our program will execute in only 3.6 nanosecond. This is why computers can do calculations so quickly.

In order to display graphics, the technique really depends on the type of display and how you communicate with it. In the old days, before fancy GPUs, the CPU would calculate what needs to be on the screen and the videocard would translate that into something that the screen can speak. In the normal RGBa colorspace that we’ve used for quite a while, the computer sees the display as a grid of pixels, with each pixel having 4 bytes of data, one for each of Red, Green, Blue, and Alpha (alpha means transparency). This is where we get the term RGB, and why RGB colors are 0-255 (the range of value available in 1 byte of data).

I hope this answers your questions, and I’d be glad to answer any followups. I’m sure I might have gotten a few details wrong, so anyone else feel free to correct me as I’m still studying this stuff.

Your computer has a processor that takes instructions in the form of binary and passes it to an electric circuit that runs the same way if you plug in the same pattern. It also has memory.

Static memory can be thought of as electricity running in a certain loop pattern, and we set that to 1 or 0 to remember things.

Computer circuits, besides memory, always respond deterministically. I like to think of it like a vertical maze with holes for incoming electron rocks on the top, and holes for output electrons in the bottom. Only gravity and the maze guides their path, therefore they’re deterministic and will always fall in the same way if you place them the same.

Imagine a simple calculator that adds numbers. It has a bunch of wires for the first and second numbers going in, and others going out for the answer. We can group a few wires together to make numbers. Like if a wire can only be 0 or 1, two wires can be 00 (0), 01 (1), 10 (2), 11 (3). The idea is to figure out this maze such that 1+2=3.

Digital logic is the discipline we use to make sense of building those mazes. In the end, your computer just takes a bunch of 0’s (an electron!) and 1’s (no electron!) and just throws them into the right mazes to give you desired output like lit! (1) and not lit! (0), etc.

At the most basic level, you’ve got a transistor. This is a device with three pins. If you apply a voltage to one of those pins, it permits current to flow between the other two. If you take away the voltage, current will no longer flow.

Now, imagine I have a pathway between high voltage and ground that passes through two of these transistors. If I look at the voltage before both transistors, it will either be equal to my high voltage or equal to ground depending on how I set the gates (control pin) of my transistors. If I set them both to ‘open’, then my output will be zero (equal to ground). If I set either to ‘closed’, then my output will be one (equal to high voltage).

This is what is known as a ‘NAND gate’. It performs the inverse of the logical operation AND.

As it turns out, you can use NAND gates to simulate any other logical gate – AND, OR, NOT, etc. – by combining them in various ways.

So now we can perform any basic logical operation.

But if we can perform any basic logical operation, that also means we can perform any basic arithmetic operation.

It also means we can build devices called ‘flip flops’ where we use logical gates feeding back into one another. This permits us to have outputs based on past inputs, or memory.

Since we now have mathematical operations and memory, all we need to do is route our outputs to an array of LED to display our outputs. Since we’ve got those transistors, we can re-route signals easily – just like a switching tracks for a train.

All you have to do at this point is scale it up to staggeringly complex levels.

If you really want a “like I’m five” answer, explaining everything from the ground up, the book you should read is “Code” by Charles Petzold. This book starts with the absolute basics of binary and switch-based logic circuits. By the end, it has shown in detail how to build a simple CPU, roughly the sophistication of the Intel 8080. And after that it explains the basics of software.

Ben Eater has an absolutely amazing series of YouTube videos that walk you through building a computer from fundamental components on bread boards. You’ll learn how everything works at the lowest levels.