Assembly 汇编代码-循环

Assembly 汇编代码-循环,assembly,x86,disassembly,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>

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

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 
0x08048445:lea-0x14(%ebp),%ebx
0x08048d48:mov-0x8(%ebx),%eax
0x08048d4b:添加-0x4(%ebx),%eax
0x08048d4e:cmp%eax,(%ebx)//比较寄存器值
0x08048d50:je 0x8048d57//如果为真,则跳转到0x08048d57
0x08048d52:调用0x8049155//否则调用func
0x08048d57:添加$0x4,%ebx//将4添加到ebx
0x08048d5a:lea-0x4(%ebp),%eax
0x08048d5d:cmp%eax,%ebx//比较寄存器值
0x08048d5f:jne 0x8048d48//如果为true,则跳转到0x08048d48
我讨厌AT&T的电话号码,但你要问的是:

  • mov
    做什么
  • 有什么区别<代码>//它令人困惑
lea
是“加载有效地址”的缩写。它加载 源操作数对源操作数的位置引用的地址 目标操作数。例如,您可以使用它来:

lea ebx, [ebx+eax*8]
进一步移动
ebx
指针
eax
项(在64位/元素数组中) 只有一条指令。基本上,你从复杂的生活中受益 x86体系结构支持的处理指针的寻址模式 效率高

这里解释的区别是:

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

u32 *ptr = %ebp - 0x14;
u32 var1 = *(ptr - 0x8);
u32 var2 = var1 + *(ptr- 0x4) ;
我讨厌AT&T的电话号码,但你要问的是:

  • mov
    做什么
  • 有什么区别<代码>//它令人困惑
lea
是“加载有效地址”的缩写。它加载 源操作数对源操作数的位置引用的地址 目标操作数。例如,您可以使用它来:

lea ebx, [ebx+eax*8]
进一步移动
ebx
指针
eax
项(在64位/元素数组中) 只有一条指令。基本上,你从复杂的生活中受益 x86体系结构支持的处理指针的寻址模式 效率高

这里解释的区别是:

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

u32 *ptr = %ebp - 0x14;
u32 var1 = *(ptr - 0x8);
u32 var2 = var1 + *(ptr- 0x4) ;
这一个有效地执行了
%ebx=%ebp-0x14
。加载有效地址指令常常被滥用,因为它能够执行非常快速的简单数学运算

mov    -0x8(%ebx),%eax
这个函数不执行
%eax=*(%ebx-0x8)
,即将
%ebx-0x8
处的值加载到
%eax

add    -0x4(%ebx),%eax
这一个没有
%eax+=*(%ebx-0x4)

这一个没有
%ebx+=4

lea    -0x4(%ebp),%eax
这一个计算
%eax=%ebp-0x4

cmp    %eax,(%ebx) //compare register values
je     0x8048d57 <phase_2+60> // if true, jump to 0x08048d57
call   0x8049155 <func> //calls func otherwise
lea    -0x4(%ebp),%eax
cmp    %eax,%ebx //compare register values
jne    0x8048d48 <phase_2+45> // if true, jump to
或者,如果您更喜欢负偏移:

for (i = 2; i < 6; i++)
{
   if (arr[i-2] + arr[i-1] != arr[i])
      func();
}
(i=2;i<6;i++)的

{
如果(arr[i-2]+arr[i-1]!=arr[i])
func();
}
这一个有效地执行了
%ebx=%ebp-0x14
。加载有效地址指令常常被滥用,因为它能够执行非常快速的简单数学运算

mov    -0x8(%ebx),%eax
这个函数不执行
%eax=*(%ebx-0x8)
,即将
%ebx-0x8
处的值加载到
%eax

add    -0x4(%ebx),%eax
这一个没有
%eax+=*(%ebx-0x4)

这一个没有
%ebx+=4

lea    -0x4(%ebp),%eax
这一个计算
%eax=%ebp-0x4

cmp    %eax,(%ebx) //compare register values
je     0x8048d57 <phase_2+60> // if true, jump to 0x08048d57
call   0x8049155 <func> //calls func otherwise
lea    -0x4(%ebp),%eax
cmp    %eax,%ebx //compare register values
jne    0x8048d48 <phase_2+45> // if true, jump to
或者,如果您更喜欢负偏移:

for (i = 2; i < 6; i++)
{
   if (arr[i-2] + arr[i-1] != arr[i])
      func();
}
(i=2;i<6;i++)的

{
如果(arr[i-2]+arr[i-1]!=arr[i])
func();
}