Fetch
The CPU is responsible for knowing which instruction it needs to take from the primary memory in order to operate correctly. To do that it sends the appropriate address through the memory (address) bus to the primary memory. The instruction that resides in the specific address is then copied into the data bus and sent to the control unit (CU).
Decode
The instruction that has been received by the CU is then decoded. Decoding an instruction allows the CPU to be aware of any additional data that are necessary for the execution of the instruction. Any required data that need to be loaded from the primary memory in order for the instruction to be executable are then fetched. The addresses of these data are placed into the memory (address) bus and the data from these addresses are received by the CPU through the data bus.
Execute
The CPU executes the instruction using the necessary data that have been loaded and calculates a result. Depending on the result, additional data may be needed. These data are fetched from the primary memory for further calculations. As before, the addresses of these data are placed into the memory (address) bus, and the data from these addresses are received by the CPU through the data bus.
Store
After executing the instruction and computing the result the CPU then stores the result in the primary memory. To do so, it specifies the address where the result will reside in the primary memory, using the memory (address) bus and sends the data through the data bus. The CPU then checks for the next instruction and repeats the steps described above by fetching, decoding, executing and finally storing the result.
So, in *real life* the CPU has many registers, not just two. There are a 16 registers that we care about in the MDR. These hold data that we need for our CPU and ALU to do their job. Think about each as a specific place on the kitchen counter. Instead of having the MDR hold the ingredients with his hands, he can place them in any of 16 spots and grab them as needed. These are shown in the table below.
The MAR is still just one register, for our purposes, and is called %rip, or register instruction pointer.
Each register can hold up to 64 bits, but if you only want to access a smaller amount of the data it holds you can use aliases for its name. For example, if you want to read the data passed through the first argument to a function, you should look into the %rdi register. If you only want to read 32 bits, then look at the %edi register, which “lives” inside the %rdi register. If you only want to read 16 bits, the look at the %si register, and so on.
In the screenshot above you can see two windows. The top window contains information in the registers. Each register either contains data or an address to an instruction. Sometimes they contain an address to data as well. You can see that this data or addresses are represented in hex form in the middle column. On the right column, you will find the decimal equivalent of the hex, if this is a piece of data, or you will find the same hex value which means that it is an address to somewhere else in memory (perhaps to another instruction)
The bottom window contains the current instruction in the MAR. This instruction is highlighted and has not been performed yet. On the left-most column, you will find an address to the instruction, akin to a page and line number in the cookbook. The next column has the name of the function we are currently performing. Next, we have the instruction to be performed followed by the data for the instruction (or a reference to which register holds the data).
To understand what each instruction does, it will be helpful for you to look at the documentation for this architecture in a nice cheat sheet form:
https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf
Let’s take a look at what’s happening above in more detail:
Line 1
Line 2
In the debugger we could perform one operation by using the stepi command. This will perform the operation and move to the next instruction.
Line 3
In this line we are using the call instruction and we are telling the computer to move execution to a new address (0x5599b292168e) in the cookbook. We’re now going to perform a new part of a recipe, you could call it a sub-recipe. This sub-recipe is called <strings_not_equal>.
If you’re a chef, phase_1 could be “Make pizza” and <strings_not_equal> would be “how to make pizza dough”.