以汇编语言开头
我正在读一本关于程序集的书,我正试着学习一点关于这种语言的知识。我有一些代码来了解他在做什么,但我遇到了麻烦。以汇编语言开头
有人请解释下面的代码是什么?
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
总结:是什么让这段代码? 我什么都不懂。
在解释的代码,所述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+8
到EAX
仍然指向堆栈中的位置。
记住:
- 进入时:ESP = X(=返回地址推入有由
CALL
)PUSH 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]
现在堆栈帧通过复制EBP
回ESP
恢复。
mov esp, ebp
pop ebp
下面一行只是做一个32位附近回报给调用者:
retn
我认为这解释了这个子程序的功能相当不错。
对于向下增长的堆栈,写入是错误的*输入时:ESP = x ...在PUSH EBP后:ESP = x + 4 * –
*然后EBP设置为:ESP = x + 4(=返回地址+4 )*我无法对这句话做出正确的回应! –
@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个数字的总和。
有时候少就是多。 –
栈也是普通的内存。所以要操纵堆栈中的值,你也可以用[esp]来解决它。进入你的程序后,[esp]指向返回地址(堆栈顶部)。 'push ebp'将存储旧的'ebp'值,[esp]现在指向旧的ebp,[esp + 4]是返回地址(堆栈“向下增长”,'push dword value'做'esp - = 4') 。然后在调用你(第一个参数)之前,'[esp + 8]'是由栈上的调用者推送的dword。当你将'esp'复制到'ebp'时,你现在可以用'[ebp + 8]'来解决它。在调试器中运行它,将存储器窗口指向esp区域,然后观察那里的值。 – Ped7g
什么使得这段代码是什么? –