0

I know there is a loop here, but I can't figure out what is going on. To be more precise, what is going on in the first three lines?

0x08048d45 <phase_2+42>:        lea    -0x14(%ebp),%ebx
0x08048d48 <phase_2+45>:        mov    -0x8(%ebx),%eax
0x08048d4b <phase_2+48>:        add    -0x4(%ebx),%eax
0x08048d4e <phase_2+51>:        cmp    %eax,(%ebx) //compare register values
0x08048d50 <phase_2+53>:        je     0x8048d57 <phase_2+60> // if true, jump to 0x08048d57
0x08048d52 <phase_2+55>:        call   0x8049155 <func> //calls func otherwise
0x08048d57 <phase_2+60>:        add    $0x4,%ebx //add 4 to ebx
0x08048d5a <phase_2+63>:        lea    -0x4(%ebp),%eax
0x08048d5d <phase_2+66>:        cmp    %eax,%ebx //compare register values
0x08048d5f <phase_2+68>:        jne    0x8048d48 <phase_2+45> // if true, jump to 0x08048d48 

2 Answers2

3
lea    -0x14(%ebp),%ebx

This one effectively does %ebx = %ebp - 0x14. The Load Effective Address instruction is often abused for its ability to perform very fast simple mathematical operations.

mov    -0x8(%ebx),%eax

This one does %eax = *(%ebx - 0x8), i.e. load the value at %ebx - 0x8 to %eax.

add    -0x4(%ebx),%eax

This one does %eax += *(%ebx - 0x4).

cmp    %eax,(%ebx) //compare register values
je     0x8048d57 <phase_2+60> // if true, jump to 0x08048d57
call   0x8049155 <func> //calls func otherwise

These three instructions are equivalent to if (%eax != *%ebx) func();

add    $0x4,%ebx //add 4 to ebx

This one does %ebx += 4.

lea    -0x4(%ebp),%eax

This one computes %eax = %ebp - 0x4.

cmp    %eax,%ebx //compare register values
jne    0x8048d48 <phase_2+45> // if true, jump to

These two are equal to do { ... } while (%eax != %ebx).

%ebp is the base pointer. It points to the point of division between the stack of the caller (the upper function) and the stack of the callee (the current function). Above it are its own saved value, the return address and arguments if any to this function (unless some register calling convention was used). Below it are the local variables, so %ebp - 0x14 is likely a pointer to an array of 32-bit integers, given that %ebx is later incremented in steps of 4 and integer additions are used. The whole assembly code should translate to something similar in C:

int arr[6];

for (i = 0; i < 4; i++)
{
   if (arr[i] + arr[i+1] != arr[i+2])
      func();
}

Or, if you'd prefer negative offsets:

for (i = 2; i < 6; i++)
{
   if (arr[i-2] + arr[i-1] != arr[i])
      func();
}
Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
2

I hate the opposite syntax in AT&T but what you are asking is:

  • what lea does?
  • what mov does?
  • what is the difference? // it is confusing

lea is an abbreviation of "load effective address". It loads the address of the location reference by the source operand to the destination operand. For instance, you could use it to:

lea ebx, [ebx+eax*8]

to move ebx pointer eax items further (in a 64-bit/element array) with a single instruction. Basically, you benefit from complex addressing modes supported by x86 architecture to manipulate pointers efficiently.

lea eax, [var] — the address of var is placed in EAX. see [here][3]

mov eax, [ebx]  ; Move the 4 bytes in memory at the address contained in EBX into EAX

and the difference explained here:

What is the difference between MOV and LEA

The 3 first line in your assembly code sets the local variables in c source code which declares the variable on the stack in the following manner:

u32 *ptr = %ebp - 0x14;
u32 var1 = *(ptr - 0x8);
u32 var2 = var1 + *(ptr- 0x4) ;
Community
  • 1
  • 1
0x90
  • 39,472
  • 36
  • 165
  • 245