我知道这里有一个循环,但我无法弄清楚发生了什么。更确切地说,前三行发生了什么?
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
答案 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,但你要问的是:
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) ;