2012-11-02 103 views
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 

回答

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

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

mov -0x8(%ebx),%eax 

这一个确实%eax = *(%ebx - 0x8),即在%ebx - 0x8值加载到%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(); 
} 
2

我讨厌AT&Topposite syntax但你问的是:

  • what lea does?
  • 什么mov呢?
  • 有什么区别? // it is confusing

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

lea ebx, [ebx+eax*8] 

进一步移动ebx指针eax项目(在64位/元件阵列) 用一条指令。基本上,您可以从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 

和差解释这里:

What is the difference between MOV and LEA

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

u32 *ptr = %ebp - 0x14; 
u32 var1 = *(ptr - 0x8); 
u32 var2 = var1 + *(ptr- 0x4) ;