ELI5: Say I've an simple addition problem (1+2). How is this problem converted into a problem the CPU can understand. And specifically what happens inside the CPU circuit when this problem is being solved? The resistors, inductors, wires... what do they actually do?

I answered part of this question in a thread not too long ago, but you also ask for all levels of abstraction from the GUI itself, so I'll try to tackle that too.

I'll start right where my other comment stops.

Ok, so let's say you've got your calculator program loaded up, and you're about to type "1+2". You look down at your keyboard and press the '1' button.

SLAP! Your CPU gets a interrupt from the keyboard. When some device wants the CPU to do things for it, it sends an interrupt (which really just means it sends current down a wire that's connected to the CPU).

Now, because the CPU got interrupted, it saves the instruction pointer at some point in memory and then jumps to the interrupt handler, which is part of the operating system. It knows where to jump because the interrupt handler instruction pointer is saved in a register (something that holds memory directly on the CPU_. The interrupt handler saves whatever the program was doing before it got interrupted, then tries to figure out what the device wants.

The CPU figures out that it was a keyboard, so then it goes to the keyboard and basically says "Hey face-slapper, what key was pressed?". It does this by reading from the arbitrary defined keyboard port (ports are like memory addresses, except for input and output of devices instead of RAM), which is usually defined to be port 96 and then storing that value somewhere. So the actual instruction that the CPU would execute would look something like

   in 96,somewhere

In assembly.

The value that would be stored in somewhere would then be 2, because that's the value the keyboard stores whenever '1' is pressed (it doesn't store 1, because 1 is the value stored when the Esc key is pressed).

The operating system looks at the 2 stored at somewhere, and then it converts that into ASCII. Now, ASCII is just a system that arbitrarily defines numbers to letters. Its usually what computer scientists use when they want to store letters and things into memory. For example, the letter '1' (not the number, the actual character) is stored as 49. After it's done converting that letter, It stores it to some list of pressed keys and goes back to whatever it was doing.

In our case, whatever it was doing was the calculator program. Oh wait no I mean it was executing the calculator program. Wait no that's violent I mean The CPUs instruction pointer was in the middle of the calculator programs instruction list and it was reading and executing its instructions.

Now, the calculator program was about to wait for the user to input some data for it to - you guessed it - calculate. In order to get user input, the program asked the operating for some user input. For our example the operating system would be a UNIX-like, (because UNIX is the holy and pure operating system, brought to us by the prophets Ken and Ritchie (and because its beautifully simple to explain)).

The line of source code in the calculator program to get 1 character of standard input and store it someplace would look something like this

read(1,stdin,someplace);

Now, the compiler (a program that converts source code to assembly and then assembly to machine code), would look at that line of code and generate something like this;

move 1,register_A //move how many characters to read into register A
move 0,register_B //move what to read from into register B (standard input is always 0)
move 0x12345678,register_C //move the address of the storage space into register C
move 2,register_syscall_number //specify the read call by placing 2 into the syscall number register
interrupt 50

What that piece of code basically does is execute a system call, which is another word for "calling the operating system and asking for a favor". It does this by specifying what it wants to happen (in our case a read), and what it wants it to happen to, (like what location it wants the read data stored to). Then, it generates an interrupt, which, as you remember, calls the interrupt handler, which is a part of the operating system, (And thus, it turns the instruction pointer over to the operating system). The 50 after the interrupt specifies that we want to do a system call, as the interrupts are numbered. (the keyboard, for example, is usually interrupt 33)

Now that were back in the operating system, we read from the registers to figure out what the program wanted us to do. In our case, It wanted user input, and we conveniently had user input to give it. We put the 49 we got earlier from the keyboard interrupt, in the someplace the program specified, and then we jump back into the program (using the instruction pointer that interrupts save).

But what If the program asked for input, and we didn't have any to give it yet?

Well that's fine too, we don't have to jump back to that program immediately, we can just pause it and run some other programs - like firefox or whatever- till we get some user input to give back to the calculator program.

Anyways, back to our case. Now the calculator program has our input. However, It also wants us to know that Its got our input. To do that, It wants to display '1' onto the screen. I'm going to cheat a little and say that It wants to display that in a terminal, (because GUIs take forever to explain). In order to do this, it does a

 write(1,stdout,someplace);

Which, exactly like the read system call, gets converted into a system call by the compiler.

Now, lets say were back in the operating system after the caclulator program did a write system call. We look and see that the calculator wants to write to stdout, so that means were going to display some output (if were not sending it out a pipe, but thats a whole 'nother story). So we need to figure out where were are going to send this data that the program is giving us. Because in our imaginary case, we only have the system console1, we can simply write this output to memory, starting at memory location 753664, because that's defined to be where the system console text memory is. Its mapped to memory rather then to a port because we access it so much.

Now when we write to that specific location in memory, the VGA (video graphics array) will look at that and decide that the number 49 looks like a '1', then it will display that '1' onto the screen.

Ok, now that we understand syscalls and a little bit of operating systems and all that jazz, let's take a look at how the calculator program will actually be written.

We want to take user input of numbers and operations. Let's simplify that by saying we want to take two numbers and one operation. Ok, so we will have a piece of code that reads in characters until they stop being numbers. We will use that piece of code to get our numbers that we need from the user. We will also have a piece of code that reads in the operation. Then, after we've gotten our numbers, We will actually do the operation, then call the write system call to display to the user our answer.

tl;dr: I should probably stop staying up late coding operating systems and get friends and go outside...

/r/explainlikeimfive Thread