x86程序集中的struct分配

时间:2014-09-05 19:17:39

标签: c assembly x86 malloc att

所以我正在尝试编写一些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。

感谢任何帮助,以及我认为您认为相关的任何内容。我对装配很新。感谢。

1 个答案:

答案 0 :(得分:10)

结构的大小为12.两个整数和指针在x86上都是4个字节,因此没有填充,结构的大小为12.您可以随时使用{{1如果你不确定类型的大小。


您正在编译而没有进行优化,因此代码似乎效率不高。

sizeof

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

我们继续前行。

malloc

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

uno

接下来是

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

我们再次将uno->second = 0; 的值加载到uno,然后写入零,这次写入偏移量为4的第二个成员

%eax

你明白了,我确定我不需要解释最后的任务。

尝试使用优化进行编译,输出看起来会非常不同。编译器应该能够将movl -12(%ebp), %eax movl $0, 4(%eax) 优化为uno,而不是将其放在堆栈中。它可以产生这个代码:

%eax

我不确定为什么你认为堆栈保留应该是16个字节。在上面的优化变体中,我只看到需要4个字节,参数传递给movl $12, (%esp) call malloc movl $0, (%eax) movl $0, 4(%eax) movl $0, 8(%eax) 。如果没有优化,我猜测是8,参数是4,局部变量是4。但我不知道为什么函数为堆栈保留了40个字节。也许答案可以在其中一个问题中找到:

最后,查看优化代码可能会更有效率。如果没有优化,编译器可能会采取许多看似奇怪的决策优化后代码将更加简洁,从长远来看,您为真实执行的代码可能已经过优化。