x86程序集中的struct分配

5 c malloc x86 assembly 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;
   }
Run Code Online (Sandbox Code Playgroud)

拆卸看起来像......

    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
Run Code Online (Sandbox Code Playgroud)

所以我有几个问题......

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

2)这是什么意思

    movl    %eax, -12(%ebp)
    movl    -12(%ebp), %eax
Run Code Online (Sandbox Code Playgroud)

是不是只是将eax的内容放入ebp-12的地址中.那么第二个语句是多余的?

3)当没有其他局部变量或参数被推入堆栈时,为什么esp会减少40?我以为它只需要递减16.

任何帮助表示赞赏,以及我认为您认为相关的任何内容.我对装配很新.谢谢.

Dav*_*nan 9

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


您正在编译而没有优化,因此代码似乎效率低下.

movl    $12, (%esp)
call    malloc
movl    %eax, -12(%ebp)
Run Code Online (Sandbox Code Playgroud)

这会调用malloc,然后将返回的值保存%eaxuno存储在的局部变量中-12(%ebp).因此,这三个指令组成了调用malloc:准备堆栈,调用函数,保存返回值.

我们继续下一行.

uno->first = 0;
Run Code Online (Sandbox Code Playgroud)

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

movl    -12(%ebp), %eax
movl    $0, (%eax)
Run Code Online (Sandbox Code Playgroud)

接下来是

uno->second = 0;
Run Code Online (Sandbox Code Playgroud)

我们再次加载unointo 的值%eax,并将此值写入零,这次是偏移量为4的第二个成员

movl    -12(%ebp), %eax
movl    $0, 4(%eax)
Run Code Online (Sandbox Code Playgroud)

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

尝试使用优化进行编译,输出看起来会非常不同.编译器应该能够优化uno%eax堆栈中而不是将它放在堆栈上.它可以产生这个代码:

movl    $12, (%esp)
call    malloc
movl    $0, (%eax)
movl    $0, 4(%eax)
movl    $0, 8(%eax)
Run Code Online (Sandbox Code Playgroud)

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

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