有什么用&QUOT的;推%EBP; MOVL%ESP,EBP%"通过GCC用于x86产生的? [英] What is the use of "push %ebp; movl %esp, %ebp" generated by GCC for x86?

查看:180
本文介绍了有什么用&QUOT的;推%EBP; MOVL%ESP,EBP%"通过GCC用于x86产生的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这两个指令导致海湾合作委员会在x86机器生成的汇编code有什么影响:

 推%EBP
MOVL%ESP,EBP%


解决方案

开卷的解释是千真万确的事实(一个小错误的方向尽管),但并没有解释为什么。

的%ebp 是基地指针为你的堆栈帧。它使用的C运行时访问堆栈中的局部变量和参数的指针。这里是由GCC生成(G ++是precise)一些典型的函数序言code首先,C ++源代码。

  // junk.c ++
INT addtwo(int类型的)
{
    INT X = 2;    返回+ X;
}

这会产生以下汇编。

  .filejunk.c ++
    。文本
.globl _Z6addtwoi
    .TYPE _Z6addtwoi,@function
_Z6addtwoi:
.LFB2:
    pushl%EBP
.LCFI0:
    MOVL%ESP,EBP%
.LCFI1:
    subl $ 16%ESP
.LCFI2:
    MOVL $ 2,-4(%EBP)
    MOVL -4(%EBP),EDX%
    MOVL 8(EBP%),%EAX
    ADDL%EDX,EAX%
    离开
    RET
.LFE2:
    .size _Z6addtwoi。-_ Z6addtwoi
    .identGCC:(Ubuntu的4.3.3-5ubuntu4)4.3.3
    .section伪.note.GNU堆栈,,@ PROGBITS

现在来解释序幕code(所有的东西之前, .LCFI2:),第一:


  1. pushl%ebp的存储的呼叫的堆栈上函数的栈帧。

  2. MOVL%ESP,EBP%接受当前堆栈指针,并把它作为框架的的名为的功能。

  3. subl $ 16%,尤其余地局部变量。

现在你的功能是可以进行工作。带有负从的%ebp%寄存器抵消任何引用您的本地变量( X 在这个例子中)。以积极的抵消任何引用的%ebp%寄存器中的参数传递。

感兴趣的最后一点是离开指令,它是一个x86汇编指令,不恢复调用函数的栈帧的工作。这通常是优化掉在以更快的动的%ebp%ESP 弹出的%ebp%序用C code。为了便于说明,然而,我并没有对所有的优化编译。

What effect these two instructions cause in the assembly code generated by gcc for x86 machines:

push %ebp
movl %esp, %ebp

解决方案

unwind's explanation is the literal truth (one minor directional error notwithstanding), but doesn't explain why.

%ebp is the "base pointer" for your stack frame. It's the pointer used by the C runtime to access local variables and parameters on the stack. Here's some typical function prologue code generated by GCC (g++ to be precise) First the C++ source.

// junk.c++
int addtwo(int a)
{
    int x = 2;

    return a + x;
}

This generates the following assembler.

.file   "junk.c++"
    .text
.globl _Z6addtwoi
    .type   _Z6addtwoi, @function
_Z6addtwoi:
.LFB2:
    pushl   %ebp
.LCFI0:
    movl    %esp, %ebp
.LCFI1:
    subl    $16, %esp
.LCFI2:
    movl    $2, -4(%ebp)
    movl    -4(%ebp), %edx
    movl    8(%ebp), %eax
    addl    %edx, %eax
    leave
    ret
.LFE2:
    .size   _Z6addtwoi, .-_Z6addtwoi
    .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
    .section    .note.GNU-stack,"",@progbits

Now to explain that prologue code (all the stuff before .LCFI2:), first:

  1. pushl %ebp stores the stack frame of the calling function on the stack.
  2. movl %esp, %ebp takes the current stack pointer and uses it as the frame for the called function.
  3. subl $16, %esp leaves room for local variables.

Now your function is ready for business. Any references with a negative offset from the %ebp% register are your local variables (x in this example). Any references with a positive offset from the %ebp% register are your parameters passed in.

The final point of interest is the leave instruction which is an x86 assembler instruction which does the work of restoring the calling function's stack frame. This is usually optimized away in to the faster move %ebp %esp and pop %ebp% sequence in C code. For illustrative purposes, however, I didn't compile with any optimizations on at all.

这篇关于有什么用&QUOT的;推%EBP; MOVL%ESP,EBP%"通过GCC用于x86产生的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆