以汇编语言开头

问题描述:

我正在读一本关于程序集的书,我正试着学习一点关于这种语言的知识。我有一些代码来了解他在做什么,但我遇到了麻烦。以汇编语言开头

有人请解释下面的代码是什么?

push ebp   //put in top the stack, right? 
mov ebp, esp  //mov the value esp to ebp 
push ecx   // ok... 
mov eax, [ebp+8] //What's ebp+8? 
add eax, [ebp+0Ch] //What's ebp+0Ch? 
add eax, [ebp+10h] //What's ebp+10h 
mov [ebp-4], eax //What's ebp-4 
mov eax, [ebp-4] 
mov esp, ebp 
pop ebp 
retn 

总结:是什么让这段代码? 我什么都不懂。

+0

栈也是普通的内存。所以要操纵堆栈中的值,你也可以用[esp]来解决它。进入你的程序后,[esp]指向返回地址(堆栈顶部)。 'push ebp'将存储旧的'ebp'值,[esp]现在指向旧的ebp,[esp + 4]是返回地址(堆栈“向下增长”,'push dword value'做'esp - = 4') 。然后在调用你(第一个参数)之前,'[esp + 8]'是由栈上的调用者推送的dword。当你将'esp'复制到'ebp'时,你现在可以用'[ebp + 8]'来解决它。在调试器中运行它,将存储器窗口指向esp区域,然后观察那里的值。 – Ped7g

+1

什么使得这段代码是什么? –

在解释的代码,所述PUSH操作码的功能,必须定义:

它递减堆栈指针,然后存储在堆栈的顶部的源操作数。

所以,首先,下面两行创建一个标准的堆栈帧。他们分配给EBP堆栈指针(ESP当前位置,这是通过引用它们相对于EBP(所谓基本指针)访问堆栈上的局部变量非常有用。

push ebp   //put in top the stack, right? 
mov ebp, esp  //mov the value esp to ebp 

现在EBP指向当前堆栈位置。

下面的行推ECX到堆栈(ESP) - 降低ESP由4. EBP保持不变。

push ecx   // ok... 

因为EBP调用时这个函数减去4(见上文),将下面的行

mov eax, [ebp+8] //What's ebp+8? 

移动第一参数EBP+8EAX仍然指向堆栈中的位置。

记住:

  • 进入时:ESP = X(=返回地址推入有由CALLPUSH EBP
  • 后:ESP = X-4(=返回地址是在ESP + 4)
  • 然后EBP被设定为:ESP = X-4(EBP = ESP = X-4(现在指向EBP的旧值))
  • 所以返回地址位于​​和第一参数位于EBP+8(32位= 4字节)。

等等这样的:

add eax, [ebp+0Ch] //What's ebp+0Ch? 

[EBP+0Ch]是第二个参数...

add eax, [ebp+10h] //What's ebp+10h 

[EBP+10h]是第三个参数。

因此,以下行将EAX复制到堆栈上的32位值。这是ECX,这是PUSH'd到上面的堆栈。

mov [ebp-4], eax //What's ebp-4 

复制回来以下行ECX局部变量是很没用......

mov eax, [ebp-4] 

现在堆栈帧通过复制EBPESP恢复。

mov esp, ebp 
pop ebp 

下面一行只是做一个32位附近回报给调用者:

retn 

我认为这解释了这个子程序的功能相当不错。

+0

对于向下增长的堆栈,写入是错误的*输入时:ESP = x ...在PUSH EBP后:ESP = x + 4 * –

+0

*然后EBP设置为:ESP = x + 4(=返回地址+4 )*我无法对这句话做出正确的回应! –

+0

@SepRoland:当然,你的权利。我修复了这个错误并添加了一些进一步的解释 – zx485

我会评论每一行与它做什么:

push ebp   //Saves EBP 
mov ebp, esp  //Establishes a pointer 
push ecx   //Creates local storage 
mov eax, [ebp+8] //This retrieves the 1st parameter 
add eax, [ebp+0Ch] //This retrieves the 2nd parameter 
add eax, [ebp+10h] //This retrieves the 3rd parameter 
mov [ebp-4], eax //This holds the original ECX, now overwritten by the sum of all 3 parameters 
mov eax, [ebp-4] //This sum is the final result in EAX 
mov esp, ebp  //Forgets about the local storage 
pop ebp   //Restores EBP 
retn    //Returns 

采用push ecx创建本地存储提供了一个较短的程序。
另一种方法是sub esp,4

所以这段代码的最终目标是计算3个数字的总和。

+1

有时候少就是多。 –