Need help in clarifying simply Assembly code and feedback about my analyzis

So I create Assembly code from C and try to understand how it works. I need your help to clarify some points and tell me if I am analysing Assembly work in a right way.

Here is C code

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);
}

And here is generated Assembly

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

So how I understand the above Assembly: 1. pushl %ebp - We push ebp first and it will point to the bottom of our main stack 2. movl %esp, %ebp - Not exactly sure what is it, but I assume we just give same address for esp as is in ebp 3. subl $24, %esp - We give address for esp 6 blocks(which are of 4 bytes) down. Meaning that esp will have address of 6th block (here I am not sure if I placed esp in a right way). I showed my stack below

.............

ebp

.............

.............

.............

.............

.............

.............

esp

.............

  • movl $10, -8(%ebp) - So we put 10 into 2nd block from the bottom of the stack
  • .............

    ebp

    .............

    .............

    10

    .............

    .............

    .............

    .............

    esp

    .............

  • movl $2, -4(%ebp) We put 2 in the 1st block from the bottom of the stack
  • .............

    ebp

    .............

    2

    .............

    10

    .............

    .............

    .............

    .............

    esp

    .............

  • movl -4(%ebp), %eax - We put 2 into the eax
  • .............

    ebp

    .............

    2 <<--- eax

    .............

    10

    .............

    .............

    .............

    .............

    esp

    .............

  • movl %eax, 4(%esp) - We put 2 from eax to the 1st block from the top of the stack
  • .............

    ebp

    .............

    2 <<--- eax

    .............

    10

    .............

    .............

    .............

    2

    .............

    esp

    .............

  • movl -8(%ebp), %eax - We put 10 into eax
  • .............

    ebp

    .............

    2

    .............

    10 <<--- eax

    .............

    .............

    .............

    2

    .............

    esp

    .............

  • movl %eax, (%esp) - We put 10 from eax in the esp .............
  • ebp

    .............

    2

    .............

    10 <<--- eax

    .............

    .............

    .............

    2

    .............

    10 <<---esp

    .............

    ret

    .............

  • call mult - we call function mult.
  • So, what I understand we prepared 2 and 10 to serve as arguments by moving them to the very top of the stack. Then we pushed return address on the very top after the arguments. So the next block after the return address will be occupied by ebp of mult function. Correct?

    Though, I do not understand why we had 2 blocks (meaning -12(%ebp) and -16(%ebp)) empty? I did not see any code in Assembly that bothered with those 2 block of 8 bytes. Why then stack of main was allocated for 24 bytes, but not 16 bytes? 1. pushl %ebp mult: .............

    2

    .............

    10

    .............

    ret

    .............

    ebp <<----

    .............

  • Not sure what .cfi_def_cfa_offset 8 .cfi_offset 5, -8 means here... What it tells us? I also not sure what movl %esp, %ebp does. It copied esp address to ebp? I understand that it is basic stack initiation.

  • subl $16, %esp . esp has address of 4th block.

  • .............

    2

    .............

    10

    .............

    ret

    .............

    ebp

    .............

    .............

    .............

    .............

    esp <<----

    .............

  • movl 8(%ebp), %eax
  • So here we copy 10 to eax

  • imull 12(%ebp), %eax Then we take second argument 2 and multiply it with 10 which is in eax.

  • movl %eax, -4(%ebp) Then we move result from eax to the stack of mult function .............

  • 2

    .............

    10

    .............

    ret

    .............

    ebp

    .............

    20 <<----

    .............

    .............

    .............

    esp

    .............

  • -4(%ebp), %eax And then we again move it back to eax? Why would we do that? Not sure the purpose of these two instructions:

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

  • They cancel each other.. no?

    Sorry for a long post. I will be thankful if you can clarify where my analysis was wrong and clarify some confusing points above.


    You are getting ahead in steps 1 and 2 of your analysis.

    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
    

    Not optimized, but that's what the function mult() does.

    链接地址: http://www.djcxy.com/p/80346.html

    上一篇: 有人可以向我解释这段代码的堆栈吗?

    下一篇: 只需要帮助澄清汇编代码和有关我的分析的反馈