Assembly 方法调用后使用EBP指针
我写了一个简单的代码来理解汇编代码。它如下所示:Assembly 方法调用后使用EBP指针,assembly,x86,Assembly,X86,我写了一个简单的代码来理解汇编代码。它如下所示: int sum(int a, int b){ int res = a+b; } 在main函数中,我调用sum函数。 所以,我得到汇编代码(这里我只取和函数的一部分)4 现在来回答我的问题。关于这一点,我有两个问题: 首先,sum参数的值(例如sum(5,4))在ebp+12和ebp+8中被选通,结果在ebp-4中被选通,这有什么原因吗?我们为什么这样做?它总是一样的还是随机选择的 第二,我们有: mov
int sum(int a, int b){
int res = a+b;
}
在main函数中,我调用sum函数。
所以,我得到汇编代码(这里我只取和函数的一部分)4
现在来回答我的问题。关于这一点,我有两个问题:
首先,sum参数的值(例如sum(5,4))在ebp+12和ebp+8中被选通,结果在ebp-4中被选通,这有什么原因吗?我们为什么这样做?它总是一样的还是随机选择的
第二,我们有:
mov DWORD PTR [ebp-4], eax
mov eax, DWORD PTR [ebp-4]
为什么我们在离开函数之前先在ebp-4中执行结果,然后再在eax中执行结果?
还有原因吗 这通常是x86系统中创建堆栈帧的方式 调用方将此转换为
push b
push a
call sum
当每个项目被推到堆栈上时,堆栈将向下增长。也就是说,堆栈指针寄存器递减四(4)个字节(在32位模式下),并将该项复制到堆栈指针寄存器指向的内存位置
push ebp ; save previous stackbase-pointer register
mov ebp, esp ; ebp = esp
此时,“调用”指令已经发出,我们现在正处于被调用例程的开始。如果我们想访问参数,我们可以像
[esp + 4] - parameter 'a'
[esp + 8] - parameter 'b'
然而,在我们为局部变量和其他东西留出空间之后,这可能会变得笨拙。因此,除了堆栈指针寄存器之外,我们还使用了堆栈基址指针寄存器。但是,我们希望stackbase指针寄存器设置为当前帧,而不是之前的函数。因此,我们将旧的堆栈保存在堆栈上(修改堆栈上参数的偏移量),然后将当前堆栈指针寄存器复制到stackbase指针寄存器
push ebp ; save previous stackbase-pointer register
mov ebp, esp ; ebp = esp
把它们放在一起。使用stackbase指针注册表访问参数
[ebp + 12] - parameter 'b'
[ebp + 8] - parameter 'a'
[ebp + 4] - return address
[ebp + 0] - saved stackbase-pointer register
资料来源:
您可以通过查找以下关键字来查找此信息:
- 呼叫约定
- 快速呼叫
- stdcall
为了给您一个明确的答案,我想请您告诉我您使用的是什么编译器。哪个操作系统和哪个编译器?您将函数声明为
int
,但没有返回任何内容