我無法理解下面的代碼如何工作。這是一段簡單的代碼,它使用遞歸函數來查找數字的階乘。在這種情況下,4*3*2*1 = 24
。爲什麼此組件產量爲24而不是4?
.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
我明白關於代碼的一切,除非我不明白爲什麼執行此部分(25/26行)。
movl 8(%ebp), %ebx
imull %ebx, %eax
我的理解(這顯然是錯誤的),是該函數將保持自稱直到%eax
值爲1。在這一點上它將乘以%eax
這是一個「4」。這將給出4的值,這對於4的階乘是完全錯誤的。然而,當我運行這個時,它確實提供了24的正確輸出。我認爲每次函數都應該執行乘法指令執行,而不是在函數完成調用之後。
有人可以通過代碼並向我解釋爲什麼代碼實際上給出了24的正確答案,而不是我認爲它應該給(4)。
而且每次在函數內部調用該函數時,ebp都會被壓入堆棧,並且會被更改爲esp。 (pushl%ebp Movl%esb,%ebp)。如果是的話,我們如何才能將esp,ebp值恢復到函數末尾的初始值。 (據我所知,pop在end_function中是做的,我們已經多次調用了這個函數,這已經推動了ebp,return,eax等幾次堆棧)。這真是令人困惑,我的組裝邏輯崩潰了。請有人解釋一下它是什麼意思,並說明什麼是堆棧,並在每個點上註冊。
你應該學會使用調試器。這些將允許您逐步瀏覽代碼並觀察發生的情況,並通過指令進行指導。從大多數代碼中剔除它。 –