c-x86程序集中的结构分配



所以我正在尝试编写一些x86来为结构分配内存。我的c代码看起来是这样的。。。

   struc *uno = malloc(sizeof(struc));
   uno->first = 0;
   uno->second = 0;
   uno->third = 0;
   //And the struct
   struct struc {
       int first;
       int second;
       int *third;
   }

拆解看起来像。。。

    pushl   %ebp
    movl    %esp, %ebp
    subl    $40, %esp
    movl    $12, (%esp)
    call    malloc
    movl    %eax, -12(%ebp)
    movl    -12(%ebp), %eax
    movl    $0, (%eax)
    movl    -12(%ebp), %eax
    movl    $0, 4(%eax)
    movl    -12(%ebp), %eax
    movl    $0, 8(%eax)
    movl    $0, %eax

所以我有几个问题。。。

1) 结构的大小是16,但为什么程序集只显示它分配了12?

2) 的意义是什么

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

它只是将eax的内容放入ebp-12的地址中。那么第二句话是多余的吗?

3) 当堆栈上没有其他本地变量或参数时,为什么esp会减少40?我本以为它只需要减少16。

感谢您的任何帮助,以及您认为相关的我可能错过的任何内容。我对组装很陌生。谢谢

结构的大小为12。这两个整数和指针在x86上都是4个字节,因此没有填充,结构的大小为12。如果您不确定类型的大小,您可以使用sizeof询问编译器。


您在编译时没有进行优化,因此代码的效率似乎有点低。

movl    $12, (%esp)
call    malloc
movl    %eax, -12(%ebp)

这将调用malloc,然后将在%eax中返回的值保存到存储在-12(%ebp)中的局部变量uno。因此,这三条指令组成了对malloc的调用:准备堆栈、调用函数、保存返回值。

我们继续下一行。

uno->first = 0;

因为没有优化,编译器没有意识到%eax已经包含uno的值,所以它再次加载它,然后将零写入第一个成员

movl    -12(%ebp), %eax
movl    $0, (%eax)

下一个是

uno->second = 0;

我们再次将uno的值加载到%eax中,并写入一个零,这一次写入偏移量为4 的第二个成员中

movl    -12(%ebp), %eax
movl    $0, 4(%eax)

你明白了,我相信我不需要解释最后的作业。

尝试进行优化编译,结果会大不相同。编译器应该能够将uno优化为%eax,而不是将其放在堆栈上。它可以产生这样的代码:

movl    $12, (%esp)
call    malloc
movl    $0, (%eax)
movl    $0, 4(%eax)
movl    $0, 8(%eax)

我真的不知道你为什么认为堆栈保留应该是16字节。在上面的优化变体中,我只看到需要4个字节,即传递给malloc的参数。如果没有优化,我想它将是8,自变量为4,局部变量为4。但我不知道为什么函数会为堆栈保留40个字节。也许答案可以在其中一个问题中找到:

  • 为什么我的编译器为函数堆栈帧保留了比所需更多的空间
  • 为什么gcc4.x在调用方法时默认为linux上的堆栈保留8个字节
  • 对齐堆栈意味着什么

最后,查看优化的代码可能会更有效率。如果不进行优化,编译器可能会做出许多看似奇怪的决定。经过优化后,代码将更加简洁,从长远来看,您实际执行的代码可能会得到优化。

相关内容

  • 没有找到相关文章