Memory 函数prolog在内存方面的应用

Memory 函数prolog在内存方面的应用,memory,assembly,stack,Memory,Assembly,Stack,我试图理解函数prolog在汇编中是如何工作的。我的书显示了以下代码: push %ebp movl %ebp, %esp 在push的定义中,它表示将ESP的值递减4(字节?),然后将操作数放入ESP指定的内存中。但是,这不会覆盖图中所示的某些数据吗? 这里我还假设每个段是4(字节?),但是我很确定函数可以有超过4字节的分配堆栈空间 接下来,第二条指令将ESP中的内容移动到EBP中,但这需要什么?已经有了吗?当调用pop时,它如何知道从堆栈中拿走多少?(我解释的

我试图理解函数prolog在汇编中是如何工作的。我的书显示了以下代码:

    push    %ebp
    movl    %ebp, %esp
在push的定义中,它表示将ESP的值递减4(字节?),然后将操作数放入ESP指定的内存中。但是,这不会覆盖图中所示的某些数据吗?

这里我还假设每个段是4(字节?),但是我很确定函数可以有超过4字节的分配堆栈空间

接下来,第二条指令将ESP中的内容移动到EBP中,但这需要什么?已经有了吗?当调用
pop
时,它如何知道从堆栈中拿走多少?(我解释的所有内容都假设指令
mov
push
从它们指向的位置开始,并在执行任何操作时进入内存)

Bula

寄存器推送消耗多少字节取决于寄存器大小,而寄存器大小又是芯片架构的一个功能。在您的示例中,您使用32位寄存器,因此每次寄存器推送将消耗4个字节

对于x86解释,这可能非常有用。

Bula

寄存器推送消耗多少字节取决于寄存器大小,而寄存器大小又是芯片架构的一个功能。在您的示例中,您使用32位寄存器,因此每次寄存器推送将消耗4个字节


对于x86解释,这可能非常有用。

x86机器上的堆栈从较高的地址向下扩展。
这可以通过
push
指令的语义反映出来:

推ebp

在语义上等同于

sub esp, 04h
mov DWORD [esp], ebp  
从技术上讲,我们说堆栈是完全下降的,因为
esp
总是指向最后一个被推上并下降的值,原因很明显

事实上,堆栈指针上方的所有内容都是由某个代码推送的,因此它被初始化并隐式分配内存。
另一方面,堆栈下的所有内容都是可用内存

因此,
push-ebp
不会覆盖任何有用的内容,一般来说,push不会覆盖任何有用的内容

mov-ebp,esp
不会获取ebp中的内容(即
mov-ebp,DWORD[esp]
,而是将esp寄存器本身的内容复制到ebp中。
使用EBP有两个原因:

  • 它隐式使用SS选择器,而其他寄存器使用DS
  • 在16位纯代码中,只有少数寄存器可用作基址,(E)BP是专门为此设计的。
    让(E)BP指向ESP的值对于随机访问堆栈和固定偏移非常方便
  • 最后,
    pop
    指令类似于
    push
    指令,其操作数决定了操作的大小:
    push ax/eax/rax
    push堆栈上分别有2、4和8个字节。
    程序员仍然有保持堆栈平衡的负担,如果需要,甚至需要对齐堆栈,但这通常要求不多


    注意:x86内存是字节可寻址的,因此当进行间接寄存器寻址时,即当我们访问寄存器中指定的地址时,如
    mov eax,DWORD[ebx]
    ,该数字以字节表示地址。

    将该数字减N意味着读取的字节数减少N个,因此从ESP中减去4将在ESP中的新地址和旧地址之间保留4个字节。

    x86机器上的堆栈将从较高的地址变为较低的地址。
    这可以通过
    push
    指令的语义反映出来:

    推ebp

    在语义上等同于

    sub esp, 04h
    mov DWORD [esp], ebp  
    
    从技术上讲,我们说堆栈是完全下降的,因为
    esp
    总是指向最后一个被推上并下降的值,原因很明显

    事实上,堆栈指针上方的所有内容都是由某个代码推送的,因此它被初始化并隐式分配内存。
    另一方面,堆栈下的所有内容都是可用内存

    因此,
    push-ebp
    不会覆盖任何有用的内容,一般来说,push不会覆盖任何有用的内容

    mov-ebp,esp
    不会获取ebp中的内容(即
    mov-ebp,DWORD[esp]
    ,而是将esp寄存器本身的内容复制到ebp中。
    使用EBP有两个原因:

  • 它隐式使用SS选择器,而其他寄存器使用DS
  • 在16位纯代码中,只有少数寄存器可用作基址,(E)BP是专门为此设计的。
    让(E)BP指向ESP的值对于随机访问堆栈和固定偏移非常方便
  • 最后,
    pop
    指令类似于
    push
    指令,其操作数决定了操作的大小:
    push ax/eax/rax
    push堆栈上分别有2、4和8个字节。
    程序员仍然有保持堆栈平衡的负担,如果需要,甚至需要对齐堆栈,但这通常要求不多


    注意:x86内存是字节可寻址的,因此当进行间接寄存器寻址时,即当我们访问寄存器中指定的地址时,如
    mov eax,DWORD[ebx]
    ,该数字以字节表示地址。

    将该数字减N意味着读取N个字节,因此从ESP中减去4将在ESP中的新地址和旧地址之间保留4个字节。

    在AT&T汇编中,您的prolog代码更像是:
    pushl%ebp
    movl%ESP,%ebp。如果是打字错误,请更正它。在AT&T汇编中,您的prolog代码更像是看起来像:
    pushl%ebp
    movl%esp,%ebp
    。如果是打字错误,请更正。当您说“esp”时,指向最后一个按下的值;