Assembly function code c

I am trying to understand the assembler code of function C. I could not understand why it andl -16was mostly executed. This is for space allocation for local variables. If so, why subl 32is it done for the main one.

I could not understand the disassembly func1. As you read, the stack grows from a higher order address to a lower order address for 8086 processors. So, that’s why there is access on the positive side of ebp (to offset parameters) and why not on the negative side of ebp. Local variables inside func1 are 3 + return address + saved registers. So it should be 20, but why is it 24? ( subl $24,esp)

#include<stdio.h>
int add(int a, int b){
 int res = 0;
 res = a + b;
 return res;
}
int func1(int a){
 int s1,s2,s3;
 s1 = add(a,a);
 s2 = add(s1,a);
 s3 = add(s1,s2);
 return s3;
}
int main(){
 int a,b;
 a = 1;b = 2;
 b = func1(a);
 printf("\n a : %d b : %d \n",a,b);
 return 0;
}

build code:

       .file   "sample.c"
        .text
.globl add
        .type   add, @function
add:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    $0, -4(%ebp)
        movl    12(%ebp), %eax
        movl    8(%ebp), %edx
        leal    (%edx,%eax), %eax
        movl    %eax, -4(%ebp)
        movl    -4(%ebp), %eax
        leave
        ret
        .size   add, .-add
.globl func1
        .type   func1, @function
func1:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    8(%ebp), %eax
        movl    %eax, 4(%esp)
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    add
        movl    %eax, -4(%ebp)
        movl    8(%ebp), %eax
        movl    %eax, 4(%esp)
        movl    -4(%ebp), %eax
        movl    %eax, (%esp)
        call    add
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        movl    %eax, 4(%esp)
        movl    -4(%ebp), %eax
        movl    %eax, (%esp)
                                      call    add
        movl    %eax, -12(%ebp)
        movl    -12(%ebp), %eax
        leave
        ret
        .size   func1, .-func1
        .section        .rodata
.LC0:
        .string "\n a : %d b : %d \n"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        subl    $32, %esp
        movl    $1, 28(%esp)
        movl    $2, 24(%esp)
        movl    28(%esp), %eax
        movl    %eax, (%esp)
        call    func1
        movl    %eax, 24(%esp)
        movl    $.LC0, %eax
        movl    24(%esp), %edx
        movl    %edx, 8(%esp)
        movl    28(%esp), %edx
        movl    %edx, 4(%esp)
        movl    %eax, (%esp)
        call    printf
        movl    $0, %eax
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
        .section        .note.GNU-stack,"",@progbits
+5
source share
2 answers

andl $-16, %esp 16 , .

, (%ebp), .

, . , - Ubuntu , ABI, , , , ABI, Intel x86. , ABI 8- , func1 24 20, 8- .

, 16 main "" , SSE, 16 16 .

, :

main, andl $-16, %esp 16 . main, 28(%esp) 24(%esp) , , 8(%esp), 4(%esp) (%esp) func1 printf. , printf, , C, C, : , C.

func1 24 20 8- . func1 8(%ebp) 4(%ebp). -12(%ebp) -4(%ebp) . 4(%esp) (%esp) add.

func1:

    - 4(%ebp) = 20(%esp): s1.
    - 8(%ebp) = 16(%esp): s2.
    -12(%ebp) = 12(%esp): s3.
    -16(%ebp) =  8(%esp): Unused padding.
    -20(%ebp) =  4(%esp): Passes second parameter of add.
    -24(%ebp) =  0(%esp): Passes first parameter of add.
+5

objdump -S, C.

+3
source

All Articles