【问题标题】:What is the purpose of this mov before call in x86 asm?在调用 x86 asm 之前这个 mov 的目的是什么?
【发布时间】:2013-10-23 15:03:32
【问题描述】:

我只是在学习 ASM/x86,所以请多多包涵。

问题

我在正在检查的程序中注意到以下内容,我认为它正在将参数传递给被调用的函数:

mov   [ebp-04],00000005
call  <some function call here>

据我所知,这似乎是将堆栈顶部的第二个字节设置为值5

这是否有效地将参数 5 传递给函数?

它会不会类似于C 中的以下内容:

void someFunction(int num); //function declaration

someFunction(5); //In some context

如果向函数传递单个参数 5,为什么将其设置为第二个字节(-04),而不是栈顶?栈顶是什么?我对这一切的解释都错了吗?

编辑 函数的顶部是设置ebp 的位置:

push  ebp
mov   ebp,esp
push  -01
push  184
mov   eax,fs:[00000000]
...   //bunch more pushes and movs with eax and ecx into [ebp-offset]
...   //a couple of jump if equals
...   //some more push and movs
lea   ecx,[ebp-1C]
mov   [ebp-04],00000005
call  <some function>

这里是被调用的函数:

 mov   edx,[ecx]
 mov   eax,[ecx+08]
 sub   eax,edx
 test  edx,edx
 je    <label1>
 cmp   eax,00000080
 jna   <label2>
 push  edx
 call  <another function>
 add   esp,04
 ret
label2:
 push  eax
 push  edx
 call  <yet another function>
 add   esp,08
label1:
 ret

【问题讨论】:

    标签: assembly x86 mov


    【解决方案1】:

    您展示的示例不是将值传递给函数。至少这不会是一个典型的电话。

    fs 寄存器的使用通常是 try/catch 设置。

    如果这真的是函数的整个序列(尤其是被调用的函数)那么

    ...这里可能只是设置了一些局部变量。

    mov   [ebp-04],00000005
    

    ...这里似乎有一个要在 ECX 寄存器中传递的参数

    lea   ecx,[ebp-1C]
    

    大多数编译程序使用ebp 寄存器作为指向堆栈上局部变量的基指针。然后使用[ebp-X] 寻址各个变量,其中X 是每个变量的偏移量。例如,如果您有两个局部 int 变量,那么在处理这两个变量时您会看到 [ebp-4][ebp-8]

    【讨论】:

    • 奇怪的是好像设置了局部变量,然后进入一个函数调用,然后在函数调用后再次将局部变量设置为另一个静态值(255)。顺便感谢您提供的额外信息!我很感激。尽我所能学习
    • 您可以设置内存访问断点,并查看该值是否在某处被访问或修改。如果您觉得这些信息有帮助,请您点赞。 ;) 这可能意味着一件事,检查是否抛出了异常。安装异常,在函数调用之前设置一个标志,如果异常没有被执行,则将值更改为其他值。只是猜测,它可能意味着完全不同的东西。
    【解决方案2】:

    ebp 不是堆栈指针,而是espebp 通常用作帧指针,因此根据它的设置方式,它可能确实将 5 作为参数传递。或者它可能只是将它存储在一个局部变量中。

    此外,在不知道函数本身的情况下,可能无法判断它是本地参数还是函数参数:

    int x = 5;
    foo();
    

    可能会生成与foo(5);相同的代码

    帧指针用于指向当前函数的堆栈区域的开头,必须由函数本身在序言中设置。参数在它上面(正偏移量)局部变量在它下面(负偏移量)。请注意,在 32 位和 64 位模式下(在 x86 上),您实际上并不需要它,因为您可以直接相对于堆栈指针 esp 进行寻址。尽管如此,在某些情况下它可能还是有用的,例如用于调试目的。

    【讨论】:

    • 我在this site 上读到了“堆栈基指针寄存器”。什么是帧指针?对不起,我的无知。
    • 所以,它是一个局部变量,因为它是一个负偏移量[ebp-04]?
    • 是的,它在当地人中。然而,其他函数的参数也可能在局部变量的底部,这就是为什么不研究被调用函数就无法判断的原因。
    • 被调用函数的顶部看起来像:mov edx,[ecx] 然后是mov eax,[ecx+08]ecx 在这里有什么价值?是在调用这个函数的函数中设置的吗?
    • 如果它是 Windows 上的 c++ 程序,它可能使用 ecx 作为 this 指针。 fs 段用于线程本地的东西和异常。被调用的函数似乎没有使用5 所以我说它不是一个参数。
    【解决方案3】:

    通常通过将参数放入寄存器或将它们压入堆栈,然后调用目标子程序来传递参数。

    EBP 通常包含指向堆栈帧的指针,而不是堆栈顶部。所以你的例子看起来很奇怪,至少它看起来不太可能是一个参数传递操作。它可能是与进行调用的函数相关的其他操作。

    是编译器生成的代码吗?如果是这样,编译器可能知道 ESP 和 EBP 之间的关系(通常在输入函数时 ESP 被复制到 ESP 中)并且可能正在利用该知识。您需要更早地弄清楚正在使用的 EBP 值的设置位置;显示该代码会很有帮助。

    【讨论】:

    • 您想要mov 指令之前的代码,还是被调用函数顶部的代码,或者两者兼而有之?
    • 现在正在努力实现它。不得不重新启动。此外,它是编译器生成的代码。
    • 在函数的顶部,我看到:push ebpmov ebp,esp,然后是 push -01。还有一些其他的函数调用和一堆[ebp+someoffset] 紧随其后。我想我现在需要找出esp 中的内容?
    • 如果您在问题文本中插入与 ebp 相关的说明会很有帮助。但听起来 ebp 在函数入口处设置为 esp (正如我所说),然后是一个 push konstant 并且没有其他有效的堆栈更改(调用推送返回地址,但返回将其弹出,对 ESP 没有净影响)。如果是这种情况,则 ebp-4 是堆栈帧中的第一个单词;它正在覆盖推送的“1”。这个值是什么,我不知道。
    • 我想我开始关注了。我仍然对为什么[ebp-4] 会是堆栈框架中的第一个单词而不是[ebp] 感到困惑。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 2019-10-30
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多