In the first module for architecture we got to know a little about the central processing unit (CPU). It was a nice high level overview of what the CPU does but it didn’t really give us all that much information about how the CPU actually accomplishes anything. If we want to understand how a program is executed on a computer we need to sit down and start to really get to know the processor and how it does what it does.
The background for this section is understanding that the CPU executes instructions on a computer and causes it to do things. We are going to look at some of the pieces of the CPU and two different types of processors.
Intel x86 CPU’s
We are going to start with the Intel x86 family of CPU’s. Intel has nicely provided a comprehensive set of software development manuals for their CPU’s. If you want to learn a lot more about how the x86 CPU’s work I suggest you read them. Even if you don’t want to learn about it just get them and keep them handy because you will need them eventually if you are serious about reverse engineering. We aren’t going to go over everything in them (Approximately 4700 pages is a little much to go over) but I’m going to hit some of the high points.
The Intel x86 processors come in two architectures, Intel 64 and IA-32. We have already discussed some of the differences between 64-bit and 32-bit architectures and we will expand on that a little more.
When an x86 processor is running it has different modes of operation based on what it is doing and what architecture it is. There are three modes for IA-32 architecture. Protected mode is the mode of normal operation. Real-address mode is the mode of operation after booting. System management mode is the mode for, you guessed it, system management. In addition to those modes 64-bit architecture adds a compatibility mode to run 16 and 32 bit binaries without recompiling (not all) and a mode to extend the address space to 64 bits.
To get the operations done the CPU has a set of tools available to it. As we discussed in Module 2 the memory is what stores the program for execution. In addition to memory the CPU has a collection of registers which allow execution of instructions. These are the tools the CPU uses to perform operations. Registers will have their own module coming up shortly. The CPU also has a data structure called the stack that we will become very familiar with when dealing with C/C++ and Assembly.
The instruction set is what allows the CPU to carry out operations. The instructions are grouped into different classifications. General-purpose instructions are for data movement, arithmetic, logic, program flow, and string operations. These are the workhorse instructions that get the tasks done.
There are special instructions that are a subset of the x86 instruction set called x87 FPU instructions. These are for dealing with floating-point values. We will see how floating-point values are treated differently when we get into some reverse engineering practice.
These two collections of instructions will be the bulk of what we see in the beginning of our journey into reverse engineering and assembly. As we encounter more specialized instructions we can add to our knowledge as necessary.
So far we have pulled back one layer on the x86 CPU. To demonstrate the differences between CPU’s we are going to take a look inside the ARMv8-A CPU. This exercise in going through the manuals is very important for us. A task may require working with something we have no understanding of in the beginning and the manual may be the only point of reference we have.
Fortunately there are also freely available manuals for the ARM architecture out there for us to grab. As I did before I suggest grabbing the manual and keeping it for a reference. If for no other reason you can read these manuals during bouts of insomnia to try and achieve some sleep. Like the x86 family the ARM architecture has 32-bit and 64-bit execution modes, AArch32 and AArch64.
ARM has three architecture profiles. If we look at these three profiles there’s an interesting catch to how they are defined. Each profile is attached to a different memory system architecture and implementation.
We have the application profile that is for a virtual memory system architecture using a memory management unit. We haven’t discussed this yet but we will get to it. A memory management unit system is a typical element of a standard desktop/laptop computer.
The second is the real-time profile. This profile supports a protected memory system architecture using a memory protection unit. This particular profile is also limited to 32-bit instruction sets.
Lastly we have the microcontroller profile. This is a variant of the real-time profile and supports a modified 32-bit instruction set.
The ARM CPU also has a set of tools to accomplish tasks. This includes registers just like the x86 CPU. However the registers are not the same ones. Like the x86 registers we will discuss the ARM registers in another module.
There are four different instruction sets mention in the ARM manual. There’s the 64-bit AArch64 instruction set, which is the only 64-bit instruction set. The AArch64 instruction set uses the 32-bit encodings. There’s the 32-bit A32 instruction set which is backwards compatible with the ARMv7 instruction set. I’ll point out here that unlike the x86 this is the first mention of backwards compatibility. There’s the T32 instruction set which can use 32 and 16 bit encodings. T32 is also backwards compatible with ARMv7. As previously mentioned there is a modified 32-bit T32 instruction set for the microcontroller profile.
Now we are starting to see that the CPU isn’t just a black box we input instructions into and get results out of. We have examined two types of CPU families. The x86 Intel family and the ARMv8 family. There are two interesting points to take away from this discussion.
The first is that each processor family has its own unique traits. The instruction sets are totally different, the execution modes/profiles are different, and the way they do things are different. The second is that there are still similarities. There are still registers and instruction sets. There are still 16, 32, and 64 bit address spaces.
Much like programming languages each type of processor may excel at different tasks. For example ARM processors can be made small with low power consumption. This may make them a preferable choice for designs running on battery power with limited space available.