Why does this assembly give 24 instead of 4?

I am having trouble understanding how the following code works. This is a simple piece of code that 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, but I don’t understand 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 continue to call itself until the %eax value is unified. At this point, he will multiply "4" by %eax , which is one. Which would give a value of 4, which is completely wrong for factorial 4. When I run this, it actually gives the correct result 24. I thought that the multiplication instruction should be executed every time the function is executed, and not after the function has completed challenge yourself.

Can someone please review the code and explain to me why the code actually gives the correct answer 24, and not what I think it should give (4).

And every time the function is called inside the function, ebp gets hit on the stack and will be changed to esp. (pushl% ebp Movl% esb,% ebp). And if so, how can we restore the value of esp, ebp to the initial value at the end of the function. (As I understand it, pop works in end_function, and we called this function several times, which made ebp, return, eax overlay several times). This really confuses my logic when the assembly falls apart. Please, someone will explain this by regulating that the hapasy is on the stack and is registered at each point.

+4
source share
1 answer

Remember that the return value of a function always goes to %eax

The build function passes and calls the factorial, decreasing %eax by 1 each time and pushing it onto the stack. When %eax is one, it finally returns. This returns you to the call factorial in the recursive call when %eax is 2, which is stored in 8(%ebp) (recall that it was pressed). So now you have 2 * 1 = 2 = %eax . Now it ends and returns again, and the process repeats until it returns to the function that called factorial in the first place.

+3
source

Source: https://habr.com/ru/post/1444238/


All Articles