在OD 反汇编关于EBP 和ESP 局部变量 和函数参数 区别 比如:

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在OD 反汇编关于EBP 和ESP 局部变量 和函数参数 区别 比如:相关的知识,希望对你有一定的参考价值。

PUSH EBP
MOV EBP,ESP
SUB ESP,4//分配局部变量空间,一个int是4个字节
MOV EAX,DWORD PTR SS:[EBP+8]//读取参数a 这里能理解 相当于 ESP-10+8
ADD EAX,DWORD PTR SS:[EBP+C]//加上参数b 这里也能理解 ESP-10+C

MOV DWORD PTR SS:[EBP-4],EAX//保存到局部变量c 这句意思没有搞清楚????

为什么是在EBP-4 中存储局部变量C 按照上面的理解 应该是 ESP-10+0 也就是EBP 中存储参数才对啊 为什么还要多减去一个4????

还有如何才OD 中区别 函数参数和局部变量???????????

MOV EAX,DWORD PTR SS:[EBP-4]//eax是返回值
MOV ESP,EBP//恢复栈顶指针
POP EBP//恢复ebp
RETN//返回

建议你找本关于汇编语言的书看看,这是堆栈平衡的问题,调用函数时,先保存EBP,再把当前ESP值赋给EBP,相当于这个函数所用的堆栈空间的起点,然后传递的参数,定义的局部变量,在程序中都是以这个EBP为参考点的,比如[EBP+8],[EBP+c]等指令,是调用压入堆栈的参数,,,一般,调用一个函数,堆栈分配是先压入参数,在压入调用程序的返回地址,再压入EBP值,再压入要保存的寄存器,如果没有可以省略,然后压入局部变量,所以压入的参数在EBP上边,调用参数一般是[EBP+x],x是偏移,而局部变量一般是[ebp-x],,根据你的描述EBP中存参数?怎么可能,EBP是个寄存器,局部变量存于堆栈中,而堆栈是内存的一部分,,EBP占四个字节的堆栈,EBP的上四个字节,即[EBP+4]存返回地址,[ebp+8]存参数,你说是存参数a,然后如果没有其他参数那么,参数b应该存于[ebp+12]的堆栈空间中,而变量存于EBP下方的堆栈空间,占4个字节,所以是[ebp-4]的堆栈空间啊,没错啊,EBP是寄存器,存地址,不存 变量,,不懂再问,追问

谢谢你的耐心打字。

参考技术A 函数参数是ebp+xxx这样的,ebp-xxx是局部变量

关于汇编中push ebp和pop ebp指令的解释

【中文标题】关于汇编中push ebp和pop ebp指令的解释【英文标题】:explanation about push ebp and pop ebp instruction in assembly 【发布时间】:2011-04-07 23:23:10 【问题描述】:

我在汇编中使用了堆栈,但我不知道 push ebp 和 pop ebp。

.intel_syntax noprefix

.include "console.i"

.text

askl:   .asciz  "Enter length: "
askb:   .asciz  "Enter breadth: "
ans:    .asciz  "Perimeter = "

_entry:

    push    ebp     # establishing stack-frame
    mov ebp, esp
    sub esp, 12

    Prompt  askl
    GetInt  [ebp-4]     # length
    Prompt  askb
    GetInt  [ebp-8]     # breadth

    mov eax, [ebp-4]    # eax = l
    add eax, [ebp-8]    # eax = l + b
    add eax, eax    # eax = 2 * (l + b)
    mov [ebp-12], eax

    Prompt  ans
    PutInt  [ebp-12]
    PutEoL

    mov esp, ebp
    pop ebp     # unwinding stack-frame
    ret

.global _entry

.end

【问题讨论】:

提供更多上下文总是最好的。也就是说,实际问题确实很模糊,需要更多解释。 【参考方案1】:

也许您对此感到疑惑:

push    ebp
mov ebp, esp
sub esp, 12

这些行被称为汇编函数序言。前 2 条指令保存前一个基指针 (ebp) 并将 EBP 设置为指向堆栈上的该位置(在返回地址的正下方)。这会将 EBP 设置为 frame pointer

sub esp,12 行正在为函数中的局部变量节省空间。可以使用[ebp - 4] 等寻址模式来寻址该空间。函数 args 的任何推入/弹出,或 call 指令本身推入返回地址,或我们调用的函数的堆栈帧,都将在当前 ESP 的此保留空间下方发生。

最后你有:

mov esp, ebp         ; restore ESP
pop ebp              ; restore caller's EBP
ret                  ; pop the return address into EIP

这是序言的反面(即尾声),因此可以恢复之前的上下文。这有时被称为“拆除”堆栈框架。

(EBP 在所有标准 x86 调用约定中都是非易失性的,也就是调用保留:如果您修改它,则必须恢复调用者的值。)

leave 指令与这两条指令完全一样,并且被一些编译器用来节省代码大小。 (enter 0,0 非常慢并且从未使用过 (https://agner.org/optimize/);leave 的效率与 mov + pop 差不多。)


请注意,使用 EBP 作为帧指针是可选,编译器不会对优化代码中的大多数函数这样做。相反,它们保存单独的元数据以允许堆栈展开/回溯。

【讨论】:

另请注意,您有一个名为 leave 的指令,这正是 mov esp, ebppop ebp 所做的。【参考方案2】:

ebp 被称为基指针或帧指针。在进入您的函数时,您推送它(以保存调用函数的值)。然后,将堆栈指针esp 复制到ebp,这样ebp 现在就指向函数的堆栈帧。然后在函数结束时弹出ebp 以便恢复调用函数的值。

为了澄清到底发生了什么——push 指令将指定寄存器(在本例中为ebp)中的值放入堆栈,并将堆栈指针递减适当的量。 pop 操作是相反的——它递增堆栈指针并从堆栈中取出一个值并将其放入指定的寄存器中。

【讨论】:

以上是关于在OD 反汇编关于EBP 和ESP 局部变量 和函数参数 区别 比如:的主要内容,如果未能解决你的问题,请参考以下文章

这是汇编程序错误吗?绑定指令

请问这段反汇编每句的含义,谢谢

为什么汇编程序员想要从这个位置减去ebp而不是esp?

一段C语言 反汇编代码,要求详解每句含义

汇编知识相关

x86汇编语言