Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 方法调用后使用EBP指针_Assembly_X86 - Fatal编程技术网

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
当时,在EAX中,16位字参数将与AX(和32位1)一起传递。返回值也将是AX/EAX。一个64位参数(或两个参数将在EDX:EAX中),并返回相同的参数。这是一个典型的FASTCALL调用约定(我相信老Pascal正在使用)

现在对于C/C++来说,fastcall通常不被使用(可能是因为它没有那么便携)。大多数东西都使用堆栈,这就是EBP发挥作用的地方。EBP是基本堆栈指针-4、-8、-12,它们只是本地堆栈中存储和返回参数的偏移指针

以下是一些链接:

为了给您一个明确的答案,我想请您告诉我您使用的是什么编译器。哪个操作系统和哪个编译器?您将函数声明为
int
,但没有返回任何内容