【问题标题】:Understanding c function in assembly理解汇编中的c函数
【发布时间】:2013-03-04 19:51:24
【问题描述】:

我正在尝试学习如何理解汇编程序中的 c 函数。我使用“gcc code.c -m32 -o code -S -fno-stack-protector”编译了以下c程序

#include <stdio.h>

void function( int a, int b, int c )
{
   char buffer1[5];
   char buffer2[10];
}

void main()
{
   function( 1, 2, 3 );
}

汇编输出如下:

        .section    __TEXT,__text,regular,pure_instructions
    .globl  _function
    .align  4, 0x90
_function:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $28, %esp
    movl    16(%ebp), %eax
    movl    12(%ebp), %ecx
    movl    8(%ebp), %edx
    movl    %edx, -4(%ebp)
    movl    %ecx, -8(%ebp)
    movl    %eax, -12(%ebp)
    addl    $28, %esp
    popl    %ebp
    ret

    .globl  _main
    .align  4, 0x90
_main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    movl    $1, (%esp)
    movl    $2, 4(%esp)
    movl    $3, 8(%esp)
    call    _function
    addl    $24, %esp
    popl    %ebp
    ret


.subsections_via_symbols

esp 和 ebp 寄存器不能相等,因为定义 int a,b,c 的偏移量在 _main 和 _function 中不同。哪一行从 ebp 中减去 4?

谢谢!

【问题讨论】:

    标签: assembly intel


    【解决方案1】:

    调用函数通常是这样的:

    1) 在函数外,参数被压入堆栈

    subl    $24, %esp
    movl    $1, (%esp)
    movl    $2, 4(%esp)
    movl    $3, 8(%esp)
    

    2) 在函数内部,在堆栈上分配空间来保存参数和局部变量。

    低于 28 美元,%esp

    在这种情况下,您有 3 个整数和 15 个字符,总共 27 个字节;这与 4 字节边界对齐。

    3) 然后将参数复制到本地堆栈空间中。

    movl    16(%ebp), %eax
    movl    12(%ebp), %ecx
    movl    8(%ebp), %edx
    movl    %edx, -4(%ebp)
    movl    %ecx, -8(%ebp)
    movl    %eax, -12(%ebp)
    

    这里,16(%ebp) 和朋友是推到外面的参数的地址,-4(%ebp) 是新分配的堆栈空间中的地址,这些值被复制到其中。

    【讨论】:

      【解决方案2】:

      没有必要在任何地方减去 4,因为它是返回地址(给定 32 位架构)将消耗堆栈上的顶部 4 个字节。

      因此,当引用堆栈上的元素时,差异为 4 美元。在call 指令之前没有推送返回地址之前 因此偏移量 $0 $4 和 $8 在 main 中很好:

      movl    $1, (%esp)
      movl    $2, 4(%esp)
      movl    $3, 8(%esp)
      

      执行:

      call    _function
      

      in main 会将 eip(返回地址)的内容压入堆栈,从而将 esp 增加 4。

      在函数中作为返回地址(消耗 4 个字节)将位于堆栈顶部,正确的偏移量是 -$4、-$8 和 -$12,这正是您的函数中使用的值:

      movl    %edx, -4(%ebp)
      movl    %ecx, -8(%ebp)
      movl    %eax, -12(%ebp)
      

      【讨论】:

      • 这是 call 指令自动将返回地址压入堆栈并将 esp 增加 4。我将把它添加到答案中以使事情清楚。
      猜你喜欢
      • 1970-01-01
      • 2015-02-24
      • 2018-01-04
      • 2023-03-22
      • 2013-04-11
      • 2019-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多