【问题标题】:Need help in clarifying simply Assembly code and feedback about my analyzis需要帮助澄清简单的汇编代码和关于我的分析的反馈
【发布时间】:2014-12-17 06:32:15
【问题描述】:

所以我用 C 创建汇编代码并尝试了解它是如何工作的。我需要你的帮助来澄清一些观点,并告诉我我是否正在以正确的方式分析装配工作。

这里是C代码

int mult(int x, int y){
    int result = x * y;
    return result;
}

int main(int argc, char *argv[]){
    int x = 10;
    int y = 2;
    return mult(x, y);
}

这里是生成的程序集

mult:
.LFB0:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $16, %esp
    movl    8(%ebp), %eax
    imull   12(%ebp), %eax
    movl    %eax, -4(%ebp)
    movl    -4(%ebp), %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc

main:
.LFB1:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $24, %esp
    movl    $10, -8(%ebp)
    movl    $2, -4(%ebp)
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    -8(%ebp), %eax
    movl    %eax, (%esp)
    call    mult
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc

那么我如何理解上述程序集: 1. pushl %ebp - 我们先 push ebp,它将指向我们主堆栈的底部 2. movl %esp, %ebp - 不完全确定它是什么,但我假设我们只是为 esp 提供与 ebp 中相同的地址 3. subl $24, %esp - 我们给出 esp 6 个块(4 个字节)的地址。这意味着 esp 将具有第 6 个块的地址(这里我不确定我是否以正确的方式放置了 esp)。我在下面展示了我的堆栈

......

ebp

......

......

......

......

......

......

特别

......

  1. movl $10, -8(%ebp) - 所以我们将 10 放入堆栈底部的第二个块中

......

ebp

......

......

10

......

......

......

......

特别

......

  1. movl $2, -4(%ebp) 我们把 2 放在栈底的第一个块中

......

ebp

......

2

......

10

......

......

......

......

特别

......

  1. movl -4(%ebp), %eax - 我们将 2 放入 eax

......

ebp

......

2

......

10

......

......

......

......

特别

......

  1. movl %eax, 4(%esp) - 我们把 2 从 eax 放到栈顶的第一个块

......

ebp

......

2

......

10

......

......

......

2

......

特别

......

  1. movl -8(%ebp), %eax - 我们将 10 放入 eax

......

ebp

......

2

......

10

......

......

......

2

......

特别

......

  1. movl %eax, (%esp) - 我们将 eax 中的 10 放入 esp ......

ebp

......

2

......

10

......

......

......

2

......

10

......

......

  1. 调用 mult - 我们调用函数 mult。

所以,据我所知,我们准备了 2 和 10 作为参数,将它们移到堆栈的最顶部。然后我们将返回地址推到参数之后的最顶部。所以返回地址之后的下一个块将被 mult 函数的 ebp 占用。对吗?

不过,我不明白为什么我们有 2 个块(意思是 -12(%ebp) 和 -16(%ebp))是空的? 我在 Assembly 中没有看到任何与这 2 个 8 字节块有关的代码。为什么 main 堆栈被分配了 24 个字节,而不是 16 个字节? 1. pushl %ebp 多: ......

2

......

10

......

......

ebp

......

  1. 不确定是什么 .cfi_def_cfa_offset 8 .cfi_offset 5, -8 这里的意思是……它告诉我们什么? 我也不确定 movl %esp, %ebp 是做什么的。它将esp地址复制到ebp? 我知道这是基本的堆栈启动。

  2. subl $16, %esp 。 esp 的地址是第 4 个块。

......

2

......

10

......

......

ebp

......

......

......

......

特别

......

  1. movl 8(%ebp), %eax

所以这里我们将 10 复制到 eax

  1. imull 12(%ebp), %eax 然后我们将第二个参数 2 与 eax 中的 10 相乘。

  2. movl %eax, -4(%ebp) 然后我们将结果从 eax 移动到 mult 函数的堆栈中 .............

2

......

10

......

......

ebp

......

20

......

......

......

特别

......

  1. -4(%ebp), %eax 然后我们又把它移回eax?我们为什么要这样做? 不确定这两条指令的用途:

    movl %eax, -4(%ebp) movl -4(%ebp), %eax

他们互相取消了......不是吗?

抱歉,发了很长的帖子。如果您能澄清我的分析错误的地方并澄清以上一些令人困惑的地方,我将不胜感激。

【问题讨论】:

  • 至少,去掉一些空白。
  • 请重新格式化此问题,以免其过长。另外,我希望你只在main 中返回mult 的结果,作为本练习的一部分——main 应该真正使用适当且有意义的返回值。在这种情况下就像EXIT_SUCCESS
  • @MikeW 如果我去掉一些空格,一切都会一团糟。如果项目之间没有空格,Stack Overflow 会将所有内容放在一行中。
  • @FemX:这不是唯一的方法。请看:stackoverflow.com/help/formatting
  • @IskarJarak 我将如何重新格式化它?不幸的是,我在 Stack Overflow 编辑窗口中没有找到任何表格视图,所以我无法以任何其他方式表示堆栈...我在每条指令之后特别显示堆栈,因为我不确定我是否以正确的方式分析所有内容

标签: c assembly


【解决方案1】:

您在分析的第 1 步和第 2 步中取得了进展。

pushl   %ebp           ;save ebp on the stack.
...
movl    %esp, %ebp     ;point ebp to the stack to access arguments and local variable space.
...
movl    %eax, -4(%ebp) ;move the product to result
movl    -4(%ebp), %eax ;return result

没有优化,但这就是函数mult() 的作用。

【讨论】:

  • 为了澄清为什么它会做那些“愚蠢”的事情 - 将%eax 移动到一个局部变量并立即返回...尝试给 gcc 提供-O 开关、-O2-O3。本质上,你“告诉” gcc 以愚蠢的方式去做。
  • 你可以说 C 函数 mult() 也在做“愚蠢的事情”,因为它在可以做 return (x * y); 时不必要地创建了一个局部变量
猜你喜欢
  • 2014-11-02
  • 2014-07-10
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 2015-08-17
  • 2012-03-16
  • 1970-01-01
相关资源
最近更新 更多