0

我知道这里有一个循环,但我不知道发生了什么。更准确地说,前三行发生了什么?

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 
4

2 回答 2

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

这有效地做到了%ebx = %ebp - 0x14。加载有效地址指令经常被滥用,因为它能够执行非常快速的简单数学运算。

mov    -0x8(%ebx),%eax

这个可以%eax = *(%ebx - 0x8),即将值加载到%ebx - 0x8to %eax

add    -0x4(%ebx),%eax

这个可以%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

这三个指令相当于if (%eax != *%ebx) func();

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

这个可以%ebx += 4

lea    -0x4(%ebp),%eax

这个计算%eax = %ebp - 0x4

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

这两个等于do { ... } while (%eax != %ebx)

%ebp是基指针。它指向调用者的堆栈(上层函数)和被调用者的堆栈(当前函数)之间的分割点。上面是它自己保存的值、返回地址和这个函数的参数(除非使用了一些寄存器调用约定)。在它下面是局部变量,因此%ebp - 0x14很可能是指向 32 位整数数组的指针,假设%ebx稍后会逐步递增4并使用整数加法。整个汇编代码应该在 C 中转换为类似的东西:

int arr[6];

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

或者,如果您更喜欢负偏移量:

for (i = 2; i < 6; i++)
{
   if (arr[i-2] + arr[i-1] != arr[i])
      func();
}
于 2012-11-02T23:15:59.820 回答
2

我讨厌相反的语法AT&T但您要问的是:

lea是“加载有效地址”的缩写。它将源操作数的位置引用的地址加载到目标操作数。例如,您可以使用它来:

lea ebx, [ebx+eax*8]

用一条指令进一步移动ebx指针项(在 64 位/元素数组中)。eax基本上,您可以从 x86 架构支持的复杂寻址模式中受益,从而有效地操作指针。

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

和这里解释的区别:

MOV和LEA有什么区别

汇编代码中的第 3 行设置源代码中的局部变量,c它以下列方式在堆栈上声明变量:

u32 *ptr = %ebp - 0x14;
u32 var1 = *(ptr - 0x8);
u32 var2 = var1 + *(ptr- 0x4) ;
于 2012-11-02T23:03:29.607 回答