Q:

Why does this assembly yield 24 instead of 4?

I am having trouble understanding how the following code works.  It is a simple piece of code which uses a recursive function to find the factorial of a number.  In this case 4*3*2*1 = 24.
.section .data
.section .text
.globl _start
._start:

 pushl $4
 call factorial
 addl $4, %esp

 movl %eax, %ebx
 movl $1, %eax
 int $0x80

 .type factorial, @function
 factorial:
 pushl %ebp
 movl %esp, %ebp
 movl 8(%ebp), %eax

 cmpl $1, %eax
 je end_factorial
 decl %eax
 pushl %eax
 call factorial
 movl 8(%ebp), %ebx
 imull %ebx, %eax

 end_factorial:
 movl %ebp, %esp
 popl %ebp
 ret

I understand everything about the code except I don't see why this section is executed (line 25/26).
movl 8(%ebp), %ebx
imull %ebx, %eax

My understanding (which is clearly wrong), is that the function will keep calling itself until the value of %eax is one.  At which point it will multiply '4' by %eax which is one.  Which would give a value of 4, which is completely wrong for the factorial of 4.  When I run this however, it does in fact give the correct output of 24.  I was thinking that the multiplication instruction should be carried out every time the function executes, rather than after the function has finished calling itself.
Can someone please go through the code and explain to me why the code is in fact giving the correct answer of 24, rather than what i think it should be giving (4).
And every time the function is called inside the function does the ebp get pushes to the stack and will be changed to the esp. (pushl %ebp
                                           Movl %esb, %ebp).  And if so how can we restore the esp,ebp value to the initial value at the end of the function. (As I understand pop is does at the end_function and we have called the function for several times which has pushed ebp, return, eax on to stack several time).  This is really confusing my logic for assembly is falling apart. Please some one explain it reguroualy saying what haapens to the stack, and registers  at each point. 

A:

Remember that the return value of a function always goes into %eax
The assembly function goes through and calls factorial, decrementing %eax by 1 each time and pushing it onto the stack. When %eax is one, it finally returns. This brings you back to call factorial in the recursive call when %eax was 2, which is stored at 8(%ebp) (recall that it was pushed). So now you have 2*1=2=%eax. Now it finishes up and returns again and the process repeats until it returns back to the function that called factorial in the first place.

