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
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.This one does
%eax = *(%ebx - 0x8), i.e. load the value at%ebx - 0x8to%eax.This one does
%eax += *(%ebx - 0x4).These three instructions are equivalent to
if (%eax != *%ebx) func();This one does
%ebx += 4.This one computes
%eax = %ebp - 0x4.These two are equal to
do { ... } while (%eax != %ebx).%ebpis 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 - 0x14is likely a pointer to an array of 32-bit integers, given that%ebxis later incremented in steps of4and integer additions are used. The whole assembly code should translate to something similar in C:Or, if you’d prefer negative offsets: