Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
So, a low-level representation of our little Multiplyfunction would usu-
ally have to take care of the following tasks:


  1. Store machine state prior to executing function code

  2. Allocate memory for z

  3. Load parameters xand yfrom memory into internal processor memory
    (registers)

  4. Multiply xby yand store the result in a register

  5. Optionally copy the multiplication result back into the memory area
    previously allocated for z

  6. Restore machine state stored earlier

  7. Return to caller and send back zas the return value


You can easily see that much of the added complexity is the result of low-
level data management considerations. The following sections introduce the
most common low-level data management constructs such as registers, stacks,
and heaps, and how they relate to higher-level concepts such as variables and
parameters.

38 Chapter 2


HIGH-LEVEL VERSUS LOW-LEVEL DATA MANAGEMENT
One question that pops to mind when we start learning about low-level
software is why are things presented in such a radically different way down
there? The fundamental problem here is execution speed in microprocessors.
In modern computers, the CPU is attached to the system memory using a
high-speed connection (a bus). Because of the high operation speed of the
CPU, the RAM isn’t readily available to the CPU. This means that the CPU can’t
just submit a read request to the RAM and expect an immediate reply, and
likewise it can’t make a write request and expect it to be completed
immediately. There are several reasons for this, but it is caused primarily by the
combined latency that the involved components introduce. Simply put, when
the CPU requests that a certain memory address be written to or read from, the
time it takes for that command to arrive at the memory chip and be processed,
and for a response to be sent back, is much longer than a single CPU clock
cycle. This means that the processor might waste precious clock cycles simply
waiting for the RAM.
This is the reason why instructions that operate directly on memory-based
operands are slower and are avoided whenever possible. The relatively lengthy
period of time each memory access takes to complete means that having a
single instruction read data from memory, operate on that data, and then write
the result back into memory might be unreasonable compared to the
processor’s own performance capabilities.
Free download pdf