我們正在研究MIPS彙編(我想這個問題可以適用於裝配雖然在一般),老師向我們介紹了幀指針。幀指針的優點是什麼?
如果我有一個函數序言,我用來直接做堆棧指針:
addiu $sp, $sp, -8 ; alloc 2 words in the stack
sw $s0, 4($sp) ; save caller function $s0 value in the stack
sw $ra, ($sp) ; save the return address for the callee function
而在函數尾聲:
move $v0, $0 ; set 0 as return value
lw $s0, 4($sp) ; pick up caller $s0 value from the stack
lw $ra, ($sp) ; pick up return address to return to the caller
addiu $sp, $sp, 8 ; dealloc the stack words I used
jr $ra ; return back to caller
老師說,使用幀指針當我們在裝配中編寫功能時對我們人類有用:
addiu $sp, $sp, -12 ; alloc 3 words in the stack
sw $fp, 8($sp) ; save caller frame pointer in the stack
addiu $fp, $sp, 8 ; set $fp to the uppermost address of the activation frame
sw $ra, -4($fp) ; saving like the first example, but relative
sw $s0, -8($fp) ; to the frame pointer
老師還說,有時候堆棧指針會繼續分配其他空間,因爲我們需要注意,所以在函數內部引用激活幀是很困難的。 使用幀指針我們將有一個指向激活幀的靜態指針。
是的,但我會永遠需要使用函數內的激活,因爲它只包含調用者函數保存的數據?
我認爲它只是使事情更難實現。有沒有一個真實的例子,幀指針對程序員來說是一個很大的優勢?
對於許多指令集,你不需要使用幀指針,最多它使編譯器作者更容易調試,這不是一個真正有效的藉口,好像浪費了一個寄存器給我。 gcc等可能允許你選擇不使用幀指針,不建立使用它的代碼來節省開銷。一些默認值,一些默認不帶。它使該函數內的偏移量固定,對於該函數,變量X始終爲fp-N。您可以爲整個功能製作X sp + M,或者可以根據需要移動SP以保留空間。 –
不管老師說什麼,結束的時候,對於那個班級來說,通過班級,懷疑一切,然後(重新)發現它,看看你是否相信。是否只是讓老師對作業進行評分更容易一些,還是這種編程規則在某種意義上被教導得「更好」?我同意它使人類更容易,但同時編譯器或人類,如果你移動sp來覆蓋函數的所有用法,沒有幀指針也同樣容易。 –
試試這個:在你的腦海中定義一個C結構,包含5個或更多字段。在堆棧中爲它分配空間。初始化它。將其成員作爲堆棧中的參數傳遞給其他函數。做和沒有框架指針。 –