如果我在堆棧框架內插入一個新的函數和指令,以彙編x86代碼,是否需要增加堆棧大小?如果是多少?當我向程序集x86中插入新指令時堆棧的幀大小?
sub 0x4, %esp
push %eax ;;new instruction
...
call fun ;; new inserted function
pop %eax ;;new instruction
.....
add 0x4, %esp
如果我在堆棧框架內插入一個新的函數和指令,以彙編x86代碼,是否需要增加堆棧大小?如果是多少?當我向程序集x86中插入新指令時堆棧的幀大小?
sub 0x4, %esp
push %eax ;;new instruction
...
call fun ;; new inserted function
pop %eax ;;new instruction
.....
add 0x4, %esp
Calling Conventions是關鍵,管理功能的調用方式,價值傳遞和返回,以及如何堆棧空間和可用的寄存器進行管理。有很多約定。知道你的函數正在使用哪一個,以及你正在調用的函數使用哪一個;他們可能會不同!
一個很常見的約定是「管理你自己的堆棧」。在這種情況下,每個函數都會分配堆棧中所需的堆棧空間量。它不需要擔心它調用的函數的堆棧空間需求;根據定義,他們將分配他們需要的(額外的)數量的堆棧空間。
「葉」函數是一個不調用其他函數的函數;每個葉函數都需要一定數量的堆棧空間。一些調用約定要求葉函數的調用者不僅爲它自己的需要分配空間,而且爲它調用的所有葉函數分配空間。這可以將調用葉函數(稱爲「最多!」)的開銷降到最低。通常,這種安排只能由編譯器完成,因爲人們難以可靠地跟蹤他們調用的所有函數以及這些函數的堆棧需求。偶爾你可能會遇到一個手寫的彙編函數,它聲明瞭它的API的一部分,調用者必須爲它分配空間。
System V ABI提供了一個「紅色區域」,其中SP的下方有128字節的堆棧,它們可用於葉子函數,它們是總是。這意味着調用者不需要分配該空間,並且小於紅色區域大小需求的葉函數只需要分配該空間即可。這是一個非常好的約定,因爲沒有函數需要擔心它是否調用葉函數,並且這可以將任意套例程鏈接在一起。
我如何知道我的函數使用哪個約定?此外,我使用的是Linux fedora 9。實際上,我正在研究SPEC基準程序之一的彙編代碼,我需要通過插入新功能和新指令來修改該代碼。 – hamb
您可仔細閱讀您的編譯器文檔。我想維基百科鏈接可能會告訴你,因爲你正在運行Linux。 –
@hamb,[Agner Fog手冊](http://www.agner.org/optimize/calling_conventions.pdf)也可能有幫助。這裏詳細描述了各種調用約定以及其他與寄存器和堆棧有關的約定。 – Eugene