汇编代码循环

时间:2012-11-02 22:46:57

标签: assembly x86 disassembly

我知道这里有一个循环,但我无法弄清楚发生了什么。更确切地说,前三行发生了什么?

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 个答案:

答案 0 :(得分:3)

lea    -0x14(%ebp),%ebx

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

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();
}

答案 1 :(得分:2)

我讨厌AT&T中的opposite 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) ;